├── 003_01_probes ├── volumes │ ├── counter.txt │ └── events.txt ├── node-app │ ├── .prettierrc │ ├── .gitignore │ ├── Dockerfile │ ├── Makefile │ ├── package.json │ ├── 01_pod_definition.yml │ ├── index.ts │ ├── README.md │ └── package-lock.json └── README.md ├── 06_tools ├── 01_install_k3s_k3d │ └── README.md ├── 007_alb_ingress │ └── 01_eks │ │ ├── k8s │ │ ├── kustomization.yaml │ │ ├── 01-foo-deployment.yml │ │ ├── 02-bar-deployment.yml │ │ └── ingress.yaml │ │ ├── cluster.yaml │ │ ├── README.md │ │ ├── rbac-role.yaml │ │ ├── Makefile │ │ ├── iam_policy.json │ │ └── v2_2_0_full.yaml ├── 06_cert_manager │ └── 01_kops │ │ ├── k8s │ │ ├── kustomization.yaml │ │ ├── 01-foo-deployment.yml │ │ ├── 02-bar-deployment.yml │ │ ├── ingress.yaml │ │ ├── cert-issues.yaml │ │ └── haproxy-ingress-controller.yaml │ │ ├── README.md │ │ ├── Makefile │ │ ├── main.tf │ │ └── cluster.yaml ├── 03_kops │ ├── kops_access_management.md │ ├── kops_intro.md │ ├── role_mappings │ │ ├── readonly-role.clusterrolebinding.yaml │ │ └── readonly-role.clusterrole.yaml │ ├── trainee.yaml │ ├── auth_configmap.yaml │ ├── Makefile │ ├── deployment.yml │ └── main.tf ├── 05_haproxy_ingress │ ├── 01_kops │ │ ├── ha_proxy_ingress.md │ │ ├── k8s │ │ │ ├── ingress.yaml │ │ │ ├── 01-foo-deployment.yml │ │ │ ├── 02-bar-deployment.yml │ │ │ └── haproxy-ingress-controller.yaml │ │ ├── Makefile │ │ └── cluster.yaml │ └── 02_eks │ │ ├── ha_proxy_ingress.md │ │ ├── k8s │ │ ├── ingress.yaml │ │ ├── node-deployment.yml │ │ └── haproxy-ingress-controller.yaml │ │ ├── Makefile │ │ └── cluster.yaml ├── 04_eks │ ├── 01_create_cluster │ │ ├── docs │ │ │ ├── comands.md │ │ │ └── intro.md │ │ ├── cluster.yaml │ │ └── Makefile │ ├── 01_pod_definition.yml │ ├── 02_access_management_control │ │ ├── deployment.yml │ │ ├── cluster.yaml │ │ ├── role_mappings │ │ │ ├── eks_developer.yaml │ │ │ └── eks_trainee.yaml │ │ ├── Makefile │ │ ├── aws_auth.yaml │ │ └── README.md │ └── kubernetes │ │ └── configmaps │ │ ├── aws-auth.yaml │ │ └── eks-console-full-access.yaml ├── 02_kustomize │ └── kustomize_intro.md └── eks_vs_kops │ └── EKS_vs_KOPS.md ├── 02_pods ├── 002_0_pods │ ├── .prettierrc │ ├── .gitignore │ ├── Dockerfile │ ├── Makefile │ ├── 01_pod_definition.yml │ ├── 02_pod_definition.yml │ ├── package.json │ ├── index.ts │ ├── README.md │ └── package-lock.json └── 002_01_pods_networking_cgroup │ ├── 01_container_networking_namespaces.md │ └── pods.md ├── 01_intro ├── 001_0_intro │ ├── node-app │ │ ├── .prettierrc │ │ ├── .gitignore │ │ ├── Dockerfile │ │ ├── tsconfig.json │ │ ├── package.json │ │ ├── index.ts │ │ └── package-lock.json │ ├── Makefile │ ├── kubernetes │ │ └── 01_pod_definition.yml │ └── README.md └── 001_1_docker_vs_kubernetes │ ├── definition.yml │ └── README.md ├── 04_services ├── 004_01_services │ ├── node-app │ │ ├── .prettierrc │ │ ├── .gitignore │ │ ├── Dockerfile │ │ ├── tsconfig.json │ │ ├── package.json │ │ ├── index.ts │ │ └── package-lock.json │ ├── Makefile │ ├── kubernetes │ │ ├── 00_pod_definition.yml │ │ └── 01_pod_definition.yml │ └── README.md └── 004_02_services_internals │ ├── kind │ ├── kind-example-config.yaml │ ├── kubernetes │ ├── 00_nginx_definition.yml │ └── 01_pod_definition.yml │ └── README.md ├── 003_00_replica_sets_and_controllers ├── node-app │ ├── .prettierrc │ ├── .gitignore │ ├── Dockerfile │ ├── tsconfig.json │ ├── Makefile │ ├── package.json │ ├── pod_definition.yml │ ├── index.ts │ └── package-lock.json └── README.md ├── .gitignore └── 007_authentication_and_authorization ├── config-demo └── README.md /003_01_probes/volumes/counter.txt: -------------------------------------------------------------------------------- 1 | 32 -------------------------------------------------------------------------------- /06_tools/01_install_k3s_k3d/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /02_pods/002_0_pods/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 120 3 | } 4 | -------------------------------------------------------------------------------- /003_01_probes/node-app/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 120 3 | } 4 | -------------------------------------------------------------------------------- /02_pods/002_0_pods/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.iml 3 | 4 | node_modules/ 5 | -------------------------------------------------------------------------------- /003_01_probes/node-app/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.iml 3 | 4 | node_modules/ 5 | -------------------------------------------------------------------------------- /01_intro/001_0_intro/node-app/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 120 3 | } 4 | -------------------------------------------------------------------------------- /01_intro/001_0_intro/node-app/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.iml 3 | 4 | node_modules/ 5 | -------------------------------------------------------------------------------- /04_services/004_01_services/node-app/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 120 3 | } 4 | -------------------------------------------------------------------------------- /003_00_replica_sets_and_controllers/node-app/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 120 3 | } 4 | -------------------------------------------------------------------------------- /04_services/004_01_services/node-app/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.iml 3 | 4 | node_modules/ 5 | -------------------------------------------------------------------------------- /003_00_replica_sets_and_controllers/node-app/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.iml 3 | 4 | node_modules/ 5 | -------------------------------------------------------------------------------- /02_pods/002_01_pods_networking_cgroup/01_container_networking_namespaces.md: -------------------------------------------------------------------------------- 1 | https://www.youtube.com/watch?v=x1npPrzyKfs 2 | 3 | -------------------------------------------------------------------------------- /02_pods/002_0_pods/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:12 2 | 3 | COPY . . 4 | WORKDIR . 5 | 6 | RUN npm install 7 | ENTRYPOINT ["npm", "start"] 8 | -------------------------------------------------------------------------------- /003_01_probes/node-app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:12 2 | 3 | COPY . . 4 | WORKDIR . 5 | 6 | RUN npm install 7 | ENTRYPOINT ["npm", "start"] 8 | -------------------------------------------------------------------------------- /01_intro/001_0_intro/node-app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:12 2 | 3 | COPY . . 4 | WORKDIR . 5 | 6 | RUN npm install 7 | ENTRYPOINT ["npm", "start"] 8 | -------------------------------------------------------------------------------- /04_services/004_01_services/node-app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:12 2 | 3 | COPY . . 4 | WORKDIR . 5 | 6 | RUN npm install 7 | ENTRYPOINT ["npm", "start"] 8 | -------------------------------------------------------------------------------- /04_services/004_02_services_internals/kind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobinNagpal/kubernetes-tutorials/HEAD/04_services/004_02_services_internals/kind -------------------------------------------------------------------------------- /06_tools/007_alb_ingress/01_eks/k8s/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - 01-foo-deployment.yml 3 | - 02-bar-deployment.yml 4 | - ingress.yaml 5 | -------------------------------------------------------------------------------- /01_intro/001_0_intro/node-app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": [ "es6", "dom" ], 4 | "resolveJsonModule": true 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /003_00_replica_sets_and_controllers/node-app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:12 2 | 3 | COPY . . 4 | WORKDIR . 5 | 6 | RUN npm install 7 | ENTRYPOINT ["npm", "start"] 8 | -------------------------------------------------------------------------------- /04_services/004_01_services/node-app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": [ "es6", "dom" ], 4 | "resolveJsonModule": true 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /003_00_replica_sets_and_controllers/node-app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": [ "es6", "dom" ], 4 | "resolveJsonModule": true 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /06_tools/06_cert_manager/01_kops/k8s/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - 01-foo-deployment.yml 3 | - 02-bar-deployment.yml 4 | - haproxy-ingress-controller.yaml 5 | - ingress.yaml 6 | -------------------------------------------------------------------------------- /04_services/004_02_services_internals/kind-example-config.yaml: -------------------------------------------------------------------------------- 1 | kind: Cluster 2 | apiVersion: kind.x-k8s.io/v1alpha4 3 | nodes: 4 | - role: control-plane 5 | - role: worker 6 | - role: worker 7 | -------------------------------------------------------------------------------- /02_pods/002_0_pods/Makefile: -------------------------------------------------------------------------------- 1 | docker-build: 2 | cd node-app && docker build . -t robinnagpal/kubernetes-tutorial-002-pods 3 | docker-push: 4 | docker push robinnagpal/kubernetes-tutorial-002-pods 5 | -------------------------------------------------------------------------------- /01_intro/001_0_intro/Makefile: -------------------------------------------------------------------------------- 1 | docker-build: 2 | cd node-app && docker build . -t robinnagpal/kubernetes-tutorial-001-node-app 3 | docker-push: 4 | docker push robinnagpal/kubernetes-tutorial-001-node-app 5 | -------------------------------------------------------------------------------- /003_00_replica_sets_and_controllers/node-app/Makefile: -------------------------------------------------------------------------------- 1 | docker-build: 2 | docker build . -t robinnagpal/kubernetes-tutorial-003-node-app 3 | docker-push: 4 | docker push robinnagpal/kubernetes-tutorial-003-node-app 5 | -------------------------------------------------------------------------------- /04_services/004_01_services/Makefile: -------------------------------------------------------------------------------- 1 | docker-build: 2 | cd node-app && docker build . -t robinnagpal/kubernetes-tutorial-004-services-node-app 3 | docker-push: 4 | docker push robinnagpal/kubernetes-tutorial-004-services-node-app 5 | -------------------------------------------------------------------------------- /06_tools/03_kops/kops_access_management.md: -------------------------------------------------------------------------------- 1 | To Debug 2 | ` aws sts assume-role --role-arn arn:aws:iam::ACCOUNT:role/ROLE --role-session-name test` 3 | ` aws sts assume-role --role-arn arn:aws:iam::617960797257:role/kubernetes_viewer --role-session-name test` 4 | -------------------------------------------------------------------------------- /02_pods/002_0_pods/01_pod_definition.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: nginx-app-pod 5 | labels: 6 | app: nginx-app 7 | spec: 8 | containers: 9 | - name: nginx-app 10 | image: nginx 11 | imagePullPolicy: Always 12 | -------------------------------------------------------------------------------- /06_tools/05_haproxy_ingress/01_kops/ha_proxy_ingress.md: -------------------------------------------------------------------------------- 1 | ## Installation 2 | https://www.haproxy.com/documentation/kubernetes/latest/installation/ 3 | 4 | ### Installation on AWS 5 | https://www.haproxy.com/documentation/kubernetes/latest/installation/community/aws/ 6 | -------------------------------------------------------------------------------- /06_tools/05_haproxy_ingress/02_eks/ha_proxy_ingress.md: -------------------------------------------------------------------------------- 1 | ## Installation 2 | https://www.haproxy.com/documentation/kubernetes/latest/installation/ 3 | 4 | ### Installation on AWS 5 | https://www.haproxy.com/documentation/kubernetes/latest/installation/community/aws/ 6 | -------------------------------------------------------------------------------- /06_tools/03_kops/kops_intro.md: -------------------------------------------------------------------------------- 1 | # Commands 2 | `kops create cluster kops.jomo.click --zones us-east-1a,us-east-1b --state=s3://kops-jomo-click-state-store --yes` 3 | 4 | `kops validate cluster kops.jomo.click --wait 10m` 5 | 6 | `kops delete cluster kops.jomo.click --yes` 7 | 8 | 9 | -------------------------------------------------------------------------------- /04_services/004_01_services/kubernetes/00_pod_definition.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: node-app-pod 5 | labels: 6 | app: node-app 7 | spec: 8 | containers: 9 | - name: node-app 10 | image: nginx 11 | imagePullPolicy: Always 12 | -------------------------------------------------------------------------------- /06_tools/04_eks/01_create_cluster/docs/comands.md: -------------------------------------------------------------------------------- 1 | `eksctl create cluster --name robin-personal-cluster --fargate` 2 | 3 | `eksctl create cluster -f cluster.yaml` 4 | 5 | 6 | `eksctl delete cluster --name robin-personal-cluster` 7 | 8 | 9 | `kubectl describe configmap -n kube-system aws-auth` 10 | -------------------------------------------------------------------------------- /06_tools/06_cert_manager/01_kops/README.md: -------------------------------------------------------------------------------- 1 | ## Route53 2 | https://cert-manager.io/docs/configuration/acme/dns01/route53/ 3 | 4 | ## Uninstall cert-manager 5 | https://docs.cert-manager.io/en/release-0.11/tasks/uninstall/kubernetes.html 6 | 7 | 8 | kubectl get cert,certificaterequest,order,challenge -A 9 | -------------------------------------------------------------------------------- /06_tools/007_alb_ingress/01_eks/cluster.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: eksctl.io/v1alpha5 2 | kind: ClusterConfig 3 | 4 | metadata: 5 | name: robin-personal-cluster 6 | region: us-east-2 7 | 8 | nodeGroups: 9 | - name: ng-1 10 | instanceType: t2.small 11 | desiredCapacity: 2 12 | volumeSize: 80 13 | ssh: 14 | allow: true 15 | -------------------------------------------------------------------------------- /06_tools/04_eks/01_create_cluster/cluster.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: eksctl.io/v1alpha5 2 | kind: ClusterConfig 3 | 4 | metadata: 5 | name: robin-personal-cluster 6 | region: us-east-2 7 | 8 | nodeGroups: 9 | - name: ng-1 10 | instanceType: t2.small 11 | desiredCapacity: 2 12 | volumeSize: 80 13 | ssh: 14 | allow: true 15 | -------------------------------------------------------------------------------- /003_01_probes/node-app/Makefile: -------------------------------------------------------------------------------- 1 | docker-build: 2 | docker build . -t robinnagpal/kubernetes-tutorial-003-01-probes 3 | 4 | docker-push: 5 | docker push robinnagpal/kubernetes-tutorial-003-01-probes 6 | 7 | start-minikube: 8 | minikube start --mount-string /Users/robintc/projects/learning/kubernetes/kubernetes-tutorials/003_01_probes/volumes:/probe_volume --mount 9 | -------------------------------------------------------------------------------- /06_tools/007_alb_ingress/01_eks/README.md: -------------------------------------------------------------------------------- 1 | ## New References 2 | https://docs.aws.amazon.com/eks/latest/userguide/aws-load-balancer-controller.html 3 | https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html 4 | 5 | ## Old References 6 | https://aws.amazon.com/blogs/opensource/kubernetes-ingress-aws-alb-ingress-controller/ 7 | https://aws.amazon.com/blogs/containers/using-alb-ingress-controller-with-amazon-eks-on-fargate/ 8 | -------------------------------------------------------------------------------- /02_pods/002_0_pods/02_pod_definition.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: node-app-deployment 5 | spec: 6 | replicas: 3 7 | selector: 8 | matchLabels: 9 | app: node-app 10 | template: 11 | metadata: 12 | labels: 13 | app: node-app 14 | spec: 15 | containers: 16 | - name: node-app 17 | image: robinnagpal/kubernetes-tutorial-002-pods:latest 18 | -------------------------------------------------------------------------------- /06_tools/04_eks/01_pod_definition.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: node-app-deployment 5 | spec: 6 | replicas: 5 7 | selector: 8 | matchLabels: 9 | app: node-app 10 | template: 11 | metadata: 12 | labels: 13 | app: node-app 14 | spec: 15 | containers: 16 | - name: node-app 17 | image: robinnagpal/kubernetes-tutorial-001-node-app:latest 18 | -------------------------------------------------------------------------------- /06_tools/03_kops/role_mappings/readonly-role.clusterrolebinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: kubernetes-readonly-clusterrole-binging 5 | subjects: 6 | - kind: Group 7 | name: kubernetes-readonly-users 8 | apiGroup: rbac.authorization.k8s.io 9 | roleRef: 10 | kind: ClusterRole 11 | name: kubernetes-readonly-clusterrole 12 | apiGroup: rbac.authorization.k8s.io 13 | -------------------------------------------------------------------------------- /003_01_probes/node-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "ts-node index.ts" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "@types/node": "^14.14.8" 13 | }, 14 | "dependencies": { 15 | "prettier": "^2.1.2", 16 | "ts-node": "^9.0.0", 17 | "typescript": "^4.0.5" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /06_tools/05_haproxy_ingress/02_eks/k8s/ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: simple-ingress 5 | spec: 6 | rules: 7 | - host: api.jomo.click 8 | http: 9 | paths: 10 | - path: / 11 | pathType: Prefix 12 | backend: 13 | service: 14 | name: node-app-service 15 | port: 16 | number: 3000 17 | -------------------------------------------------------------------------------- /01_intro/001_0_intro/node-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "ts-node index.ts" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "@types/node": "^14.14.8" 13 | }, 14 | "dependencies": { 15 | "prettier": "^2.1.2", 16 | "ts-node": "^9.0.0", 17 | "typescript": "^4.0.5" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /06_tools/04_eks/02_access_management_control/deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: backend-deployment 5 | spec: 6 | replicas: 5 7 | selector: 8 | matchLabels: 9 | app: node-app 10 | template: 11 | metadata: 12 | labels: 13 | app: node-app 14 | spec: 15 | containers: 16 | - name: node-app 17 | image: robinnagpal/kubernetes-tutorial-003-node-app:latest 18 | -------------------------------------------------------------------------------- /06_tools/04_eks/01_create_cluster/Makefile: -------------------------------------------------------------------------------- 1 | create_cluster: 2 | eksctl create cluster -f cluster.yaml 3 | 4 | delete_cluster: 5 | eksctl delete cluster -f cluster.yaml 6 | 7 | describe_cluster: 8 | eksctl utils describe-stacks --region=us-east-2 --cluster=robin-personal-cluster 9 | 10 | aws_identity: 11 | aws sts get-caller-identity 12 | 13 | set_context: 14 | eksctl utils write-kubeconfig --cluster=robin-personal-cluster --set-kubeconfig-context=true 15 | -------------------------------------------------------------------------------- /02_pods/002_0_pods/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node_modules/.bin/ts-node index.ts" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "@types/node": "^14.14.8" 13 | }, 14 | "dependencies": { 15 | "prettier": "^2.1.2", 16 | "ts-node": "^9.0.0", 17 | "typescript": "^4.0.5" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /04_services/004_01_services/node-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "ts-node index.ts" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "@types/node": "^14.14.8" 13 | }, 14 | "dependencies": { 15 | "prettier": "^2.1.2", 16 | "ts-node": "^9.0.0", 17 | "typescript": "^4.0.5" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /04_services/004_02_services_internals/kubernetes/00_nginx_definition.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: nginx-deployment 5 | spec: 6 | replicas: 3 7 | selector: 8 | matchLabels: 9 | app: nginx 10 | template: 11 | metadata: 12 | labels: 13 | app: nginx 14 | spec: 15 | containers: 16 | - name: nginx 17 | image: nginx 18 | tty: true 19 | stdin: true 20 | -------------------------------------------------------------------------------- /003_00_replica_sets_and_controllers/node-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "ts-node index.ts" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "@types/node": "^14.14.8" 13 | }, 14 | "dependencies": { 15 | "prettier": "^2.1.2", 16 | "ts-node": "^9.0.0", 17 | "typescript": "^4.0.5" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /06_tools/04_eks/02_access_management_control/cluster.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: eksctl.io/v1alpha5 2 | kind: ClusterConfig 3 | 4 | metadata: 5 | name: robin-personal-cluster 6 | region: us-east-2 7 | 8 | nodeGroups: 9 | - name: ng-1 10 | instanceType: t2.small 11 | desiredCapacity: 2 12 | volumeSize: 80 13 | ssh: 14 | allow: true 15 | - name: ng-2 16 | instanceType: t2.small 17 | desiredCapacity: 2 18 | volumeSize: 80 19 | ssh: 20 | allow: true 21 | -------------------------------------------------------------------------------- /06_tools/02_kustomize/kustomize_intro.md: -------------------------------------------------------------------------------- 1 | ## Introduction 2 | Kustomize lets you customize raw, template-free YAML files for multiple purposes, leaving the original YAML 3 | untouched and usable as is. 4 | 5 | Kustomize is like Kubernetes, it is totally declarative ! You say what you want and the system provides it to you. 6 | You don’t have to follow the imperative way and describe how you want it to build the thing. 7 | 8 | ## Commands 9 | To see what will be applied in your cluster, we will mainly use in the command `kustomize build` instead of `kubectl apply -k`. 10 | 11 | 12 | -------------------------------------------------------------------------------- /06_tools/03_kops/role_mappings/readonly-role.clusterrole.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: kubernetes-readonly-clusterrole 5 | rules: 6 | - apiGroups: 7 | - "" 8 | resources: [ "*"] 9 | verbs: 10 | - get 11 | - list 12 | - watch 13 | - apiGroups: 14 | - extensions 15 | resources: [ "*" ] 16 | verbs: 17 | - get 18 | - list 19 | - watch 20 | - apiGroups: 21 | - apps 22 | resources: [ "*" ] 23 | verbs: 24 | - get 25 | - list 26 | - watch 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | backend/.gradle/* 2 | backend/build/* 3 | /sql/.gradle 4 | backend/.idea/* 5 | .idea/* 6 | *.iml 7 | .gradle/* 8 | 9 | */**/.envrc 10 | */**/local_kube_config.yaml 11 | */**/local_kube_config.yaml.eksctl.lock 12 | 13 | */**/hidden.csv 14 | */**/hidden.txt 15 | */**/hidden.md 16 | */**/.terraform 17 | */**/.terraform.lock.hcl 18 | 19 | .DS_Store 20 | 21 | /backend/schema*.sql 22 | 23 | 24 | /sql/gradle/ 25 | /sql/gradlew 26 | /sql/gradlew.bat 27 | 28 | /backend/out 29 | 30 | backend/src/integrationTest/kotlin/sg/floenergy/energycore/exposed_dump.sql 31 | backend/src/integrationTest/kotlin/sg/floenergy/energycore/flyaway_dump.sql 32 | -------------------------------------------------------------------------------- /003_00_replica_sets_and_controllers/node-app/pod_definition.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: node-app-pod 5 | labels: 6 | app: node-app 7 | spec: 8 | containers: 9 | - name: node-app 10 | image: robinnagpal/kubernetes-tutorial-003-node-app:latest 11 | 12 | --- 13 | apiVersion: v1 14 | kind: Service 15 | metadata: 16 | name: node-app-service 17 | spec: 18 | type: LoadBalancer 19 | selector: 20 | app: node-app 21 | ports: 22 | - port: 80 23 | targetPort: 3000 24 | nodePort: 30464 25 | sessionAffinity: None 26 | sessionAffinityConfig: 27 | clientIP: 28 | timeoutSeconds: 1 29 | -------------------------------------------------------------------------------- /02_pods/002_0_pods/index.ts: -------------------------------------------------------------------------------- 1 | import { createServer, IncomingMessage, ServerResponse } from "http"; 2 | import { hostname } from "os"; 3 | 4 | const port = 8080; 5 | const server = createServer((request: IncomingMessage, response: ServerResponse) => { 6 | switch (request.url) { 7 | case "/node-app": { 8 | if (request.method === "GET") { 9 | response.setHeader("Connection", "close"); 10 | response.end(`Hello world from ${hostname()}`); 11 | } 12 | break; 13 | } 14 | default: { 15 | response.statusCode = 404; 16 | response.end("Unknown path"); 17 | } 18 | } 19 | }); 20 | 21 | server.listen(port); 22 | 23 | -------------------------------------------------------------------------------- /04_services/004_01_services/kubernetes/01_pod_definition.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: nginx-app-deployment 5 | spec: 6 | replicas: 5 7 | selector: 8 | matchLabels: 9 | app: nginx-app 10 | template: 11 | metadata: 12 | labels: 13 | app: nginx-app 14 | spec: 15 | containers: 16 | - name: nginx-app 17 | image: nginx 18 | 19 | 20 | --- 21 | apiVersion: v1 22 | kind: Service 23 | metadata: 24 | name: nginx-app-service 25 | spec: 26 | type: NodePort 27 | selector: 28 | app: nginx-app 29 | ports: 30 | - port: 80 31 | targetPort: 80 32 | nodePort: 30464 33 | -------------------------------------------------------------------------------- /06_tools/05_haproxy_ingress/02_eks/k8s/node-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: backend-deployment 5 | spec: 6 | replicas: 4 7 | selector: 8 | matchLabels: 9 | app: node-app 10 | template: 11 | metadata: 12 | labels: 13 | app: node-app 14 | spec: 15 | containers: 16 | - name: node-app 17 | image: robinnagpal/kubernetes-tutorial-003-node-app:latest 18 | 19 | --- 20 | apiVersion: v1 21 | kind: Service 22 | metadata: 23 | name: node-app-service 24 | spec: 25 | type: ClusterIP 26 | selector: 27 | app: node-app 28 | ports: 29 | - port: 3000 30 | targetPort: 3000 31 | -------------------------------------------------------------------------------- /04_services/004_02_services_internals/kubernetes/01_pod_definition.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: node-app-deployment 5 | spec: 6 | replicas: 3 7 | selector: 8 | matchLabels: 9 | app: node-app 10 | template: 11 | metadata: 12 | labels: 13 | app: node-app 14 | spec: 15 | containers: 16 | - name: node-app 17 | image: robinnagpal/kubernetes-tutorial-004-services-node-app:latest 18 | 19 | --- 20 | apiVersion: v1 21 | kind: Service 22 | metadata: 23 | name: node-app-service 24 | spec: 25 | type: ClusterIP 26 | selector: 27 | app: node-app 28 | ports: 29 | - port: 80 30 | targetPort: 3000 31 | -------------------------------------------------------------------------------- /06_tools/05_haproxy_ingress/01_kops/k8s/ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: simple-ingress 5 | spec: 6 | rules: 7 | - host: foo.jomo.click 8 | http: 9 | paths: 10 | - path: / 11 | pathType: Prefix 12 | backend: 13 | service: 14 | name: foo-app-service 15 | port: 16 | number: 3000 17 | - host: bar.jomo.click 18 | http: 19 | paths: 20 | - path: / 21 | pathType: Prefix 22 | backend: 23 | service: 24 | name: bar-app-service 25 | port: 26 | number: 3000 27 | -------------------------------------------------------------------------------- /01_intro/001_0_intro/node-app/index.ts: -------------------------------------------------------------------------------- 1 | import { createServer, IncomingMessage, ServerResponse } from "http"; 2 | import { hostname } from "os"; 3 | 4 | const port = 3000; 5 | 6 | let counter = 0; 7 | const server = createServer((request: IncomingMessage, response: ServerResponse) => { 8 | switch (request.url) { 9 | case "/node-app": { 10 | if (request.method === "GET") { 11 | response.setHeader("Connection", "close"); 12 | response.end(`Hello world ${counter} from ${hostname()}`); 13 | } 14 | counter = counter + 1; 15 | break; 16 | } 17 | default: { 18 | response.statusCode = 404; 19 | response.end("Unknown path"); 20 | } 21 | } 22 | }); 23 | 24 | server.listen(port); 25 | -------------------------------------------------------------------------------- /04_services/004_01_services/node-app/index.ts: -------------------------------------------------------------------------------- 1 | import { createServer, IncomingMessage, ServerResponse } from "http"; 2 | import { hostname } from "os"; 3 | 4 | const port = 3000; 5 | 6 | let counter = 0; 7 | const server = createServer((request: IncomingMessage, response: ServerResponse) => { 8 | switch (request.url) { 9 | case "/node-app": { 10 | if (request.method === "GET") { 11 | counter = counter + 1; 12 | response.setHeader("Connection", "close"); 13 | response.end(`Hello world ${counter} from ${hostname()}`); 14 | } 15 | break; 16 | } 17 | default: { 18 | response.statusCode = 404; 19 | response.end("Unknown path"); 20 | } 21 | } 22 | }); 23 | 24 | server.listen(port); 25 | -------------------------------------------------------------------------------- /06_tools/007_alb_ingress/01_eks/k8s/01-foo-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: foo-backend-deployment 5 | spec: 6 | replicas: 4 7 | selector: 8 | matchLabels: 9 | app: foo-app 10 | template: 11 | metadata: 12 | labels: 13 | app: foo-app 14 | spec: 15 | containers: 16 | - name: foo-app 17 | image: robinnagpal/kubernetes-tutorial-003-node-app:latest 18 | env: 19 | - name: APP_NAME 20 | value: foo 21 | 22 | --- 23 | apiVersion: v1 24 | kind: Service 25 | metadata: 26 | name: foo-app-service 27 | spec: 28 | type: NodePort 29 | selector: 30 | app: foo-app 31 | ports: 32 | - port: 3000 33 | targetPort: 3000 34 | -------------------------------------------------------------------------------- /06_tools/007_alb_ingress/01_eks/k8s/02-bar-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: bar-backend-deployment 5 | spec: 6 | replicas: 4 7 | selector: 8 | matchLabels: 9 | app: bar-app 10 | template: 11 | metadata: 12 | labels: 13 | app: bar-app 14 | spec: 15 | containers: 16 | - name: bar-app 17 | image: robinnagpal/kubernetes-tutorial-003-node-app:latest 18 | env: 19 | - name: APP_NAME 20 | value: bar 21 | 22 | --- 23 | apiVersion: v1 24 | kind: Service 25 | metadata: 26 | name: bar-app-service 27 | spec: 28 | type: NodePort 29 | selector: 30 | app: bar-app 31 | ports: 32 | - port: 3000 33 | targetPort: 3000 34 | -------------------------------------------------------------------------------- /06_tools/06_cert_manager/01_kops/k8s/01-foo-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: foo-backend-deployment 5 | spec: 6 | replicas: 4 7 | selector: 8 | matchLabels: 9 | app: foo-app 10 | template: 11 | metadata: 12 | labels: 13 | app: foo-app 14 | spec: 15 | containers: 16 | - name: foo-app 17 | image: robinnagpal/kubernetes-tutorial-003-node-app:latest 18 | env: 19 | - name: APP_NAME 20 | value: foo 21 | 22 | --- 23 | apiVersion: v1 24 | kind: Service 25 | metadata: 26 | name: foo-app-service 27 | spec: 28 | type: ClusterIP 29 | selector: 30 | app: foo-app 31 | ports: 32 | - port: 3000 33 | targetPort: 3000 34 | -------------------------------------------------------------------------------- /06_tools/06_cert_manager/01_kops/k8s/02-bar-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: bar-backend-deployment 5 | spec: 6 | replicas: 4 7 | selector: 8 | matchLabels: 9 | app: bar-app 10 | template: 11 | metadata: 12 | labels: 13 | app: bar-app 14 | spec: 15 | containers: 16 | - name: bar-app 17 | image: robinnagpal/kubernetes-tutorial-003-node-app:latest 18 | env: 19 | - name: APP_NAME 20 | value: bar 21 | 22 | --- 23 | apiVersion: v1 24 | kind: Service 25 | metadata: 26 | name: bar-app-service 27 | spec: 28 | type: ClusterIP 29 | selector: 30 | app: bar-app 31 | ports: 32 | - port: 3000 33 | targetPort: 3000 34 | -------------------------------------------------------------------------------- /01_intro/001_1_docker_vs_kubernetes/definition.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: backend-deployment 5 | spec: 6 | replicas: 5 7 | selector: 8 | matchLabels: 9 | app: node-app 10 | template: 11 | metadata: 12 | labels: 13 | app: node-app 14 | spec: 15 | containers: 16 | - name: node-app 17 | image: backend:latest 18 | 19 | --- 20 | apiVersion: v1 21 | kind: Service 22 | metadata: 23 | name: node-app-service 24 | spec: 25 | type: LoadBalancer 26 | selector: 27 | app: node-app 28 | ports: 29 | - port: 80 30 | targetPort: 3000 31 | nodePort: 30464 32 | sessionAffinity: None 33 | sessionAffinityConfig: 34 | clientIP: 35 | timeoutSeconds: 1 36 | -------------------------------------------------------------------------------- /06_tools/05_haproxy_ingress/01_kops/k8s/01-foo-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: foo-backend-deployment 5 | spec: 6 | replicas: 4 7 | selector: 8 | matchLabels: 9 | app: foo-app 10 | template: 11 | metadata: 12 | labels: 13 | app: foo-app 14 | spec: 15 | containers: 16 | - name: foo-app 17 | image: robinnagpal/kubernetes-tutorial-003-node-app:latest 18 | env: 19 | - name: APP_NAME 20 | value: foo 21 | 22 | --- 23 | apiVersion: v1 24 | kind: Service 25 | metadata: 26 | name: foo-app-service 27 | spec: 28 | type: ClusterIP 29 | selector: 30 | app: foo-app 31 | ports: 32 | - port: 3000 33 | targetPort: 3000 34 | -------------------------------------------------------------------------------- /06_tools/05_haproxy_ingress/01_kops/k8s/02-bar-deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: bar-backend-deployment 5 | spec: 6 | replicas: 4 7 | selector: 8 | matchLabels: 9 | app: bar-app 10 | template: 11 | metadata: 12 | labels: 13 | app: bar-app 14 | spec: 15 | containers: 16 | - name: bar-app 17 | image: robinnagpal/kubernetes-tutorial-003-node-app:latest 18 | env: 19 | - name: APP_NAME 20 | value: bar 21 | 22 | --- 23 | apiVersion: v1 24 | kind: Service 25 | metadata: 26 | name: bar-app-service 27 | spec: 28 | type: ClusterIP 29 | selector: 30 | app: bar-app 31 | ports: 32 | - port: 3000 33 | targetPort: 3000 34 | -------------------------------------------------------------------------------- /06_tools/04_eks/kubernetes/configmaps/aws-auth.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: aws-auth 5 | namespace: kube-system 6 | data: 7 | mapRoles: | 8 | - groups: 9 | - system:bootstrappers 10 | - system:nodes 11 | - system:node-proxier 12 | rolearn: arn:aws:iam::250327115872:role/eksctl-robin-personal-clus-FargatePodExecutionRole-1PQBJCBK5RR92 13 | username: system:node:{{SessionName}} 14 | mapUsers: | 15 | - userarn: arn:aws:iam::250327115872:user/robin-aws 16 | username: robin-aws 17 | groups: 18 | - system:masters 19 | - system:discovery 20 | - userarn: arn:aws:iam::250327115872:user/robin-aws 21 | username: robin-aws 22 | groups: 23 | - system:masters 24 | - system:discovery 25 | -------------------------------------------------------------------------------- /01_intro/001_0_intro/kubernetes/01_pod_definition.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: node-app-deployment 5 | spec: 6 | replicas: 5 7 | selector: 8 | matchLabels: 9 | app: node-app 10 | template: 11 | metadata: 12 | labels: 13 | app: node-app 14 | spec: 15 | containers: 16 | - name: node-app 17 | image: robinnagpal/kubernetes-tutorial-001-node-app:latest 18 | 19 | --- 20 | apiVersion: v1 21 | kind: Service 22 | metadata: 23 | name: node-app-service 24 | spec: 25 | type: LoadBalancer 26 | selector: 27 | app: node-app 28 | ports: 29 | - port: 80 30 | targetPort: 3000 31 | nodePort: 30464 32 | sessionAffinity: None 33 | sessionAffinityConfig: 34 | clientIP: 35 | timeoutSeconds: 1 36 | -------------------------------------------------------------------------------- /06_tools/03_kops/trainee.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: trainee-clusterrole 5 | rules: 6 | - apiGroups: [""] 7 | resources: ["nodes", "namespaces", "pods"] 8 | verbs: ["get", "list"] 9 | - apiGroups: ["apps"] 10 | resources: ["deployments" ,"daemonsets" ,"statefulsets" ,"replicasets"] 11 | verbs: ["get", "list"] 12 | - apiGroups: [ "batch"] 13 | resources: ["jobs"] 14 | verbs: ["get", "list"] 15 | --- 16 | apiVersion: rbac.authorization.k8s.io/v1 17 | kind: ClusterRoleBinding 18 | metadata: 19 | name: trainee-clusterrole-binging 20 | subjects: 21 | - kind: Group 22 | name: kubernetes_viewer 23 | apiGroup: rbac.authorization.k8s.io 24 | roleRef: 25 | kind: ClusterRole 26 | name: trainee-clusterrole 27 | apiGroup: rbac.authorization.k8s.io 28 | -------------------------------------------------------------------------------- /06_tools/03_kops/auth_configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | namespace: kube-system 5 | name: aws-iam-authenticator 6 | labels: 7 | k8s-app: aws-iam-authenticator 8 | data: 9 | config.yaml: | 10 | clusterID: kops.jomo.click 11 | server: 12 | mapRoles: 13 | - roleARN: arn:aws:iam::617960797257:role/kubernetes_readonly_users_role 14 | username: kubernetes_readonly_users_role 15 | groups: 16 | - kubernetes-readonly-users 17 | mapUsers: 18 | - userARN: arn:aws:iam::617960797257:user/tf-test-developers1 19 | username: tf-test-developers1 20 | groups: 21 | - system:masters 22 | - userARN: arn:aws:iam::617960797257:user/robin-kops-aws-test 23 | username: robin-kops-aws-test 24 | groups: 25 | - system:masters 26 | -------------------------------------------------------------------------------- /02_pods/002_01_pods_networking_cgroup/pods.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Pods networking in AWS 4 | https://www.youtube.com/watch?v=7LRtytR6ZbA 5 | 6 | 7 | # Shared storage 8 | https://kubernetes.io/docs/concepts/workloads/pods/#pod-storage 9 | 10 | # Shared Networking 11 | https://kubernetes.io/docs/concepts/workloads/pods/#pod-networking 12 | 13 | 14 | 15 | https://sookocheff.com/post/kubernetes/understanding-kubernetes-networking-model/#:~:text=In%20terms%20of%20Docker%20constructs,reside%20in%20the%20same%20namespace. 16 | 17 | 18 | 19 | 20 | **Good Article that explains pod, service, ingress networking.** 21 | - https://medium.com/google-cloud/understanding-kubernetes-networking-pods-7117dd28727 22 | 23 | Very nice presentation on container communication 24 | - https://kccna18.sched.com/event/GrWx/container-networking-from-scratch-kristen-jacobs-oracle 25 | -------------------------------------------------------------------------------- /06_tools/06_cert_manager/01_kops/k8s/ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: simple-ingress 5 | spec: 6 | rules: 7 | - host: foo.jomo.click 8 | http: 9 | paths: 10 | - path: / 11 | pathType: Prefix 12 | backend: 13 | service: 14 | name: foo-app-service 15 | port: 16 | number: 3000 17 | - host: bar.jomo.click 18 | http: 19 | paths: 20 | - path: / 21 | pathType: Prefix 22 | backend: 23 | service: 24 | name: bar-app-service 25 | port: 26 | number: 3000 27 | tls: 28 | - hosts: 29 | - foo.jomo.click 30 | - bar.jomo.click 31 | secretName: tls-keys 32 | 33 | -------------------------------------------------------------------------------- /06_tools/04_eks/01_create_cluster/docs/intro.md: -------------------------------------------------------------------------------- 1 | An Amazon EKS cluster consists of two primary components: 2 | 1) EKS Control Plane 3 | 2) EKS nodes 4 | 5 | 6 | When you create a new cluster, Amazon EKS creates an endpoint for the managed 7 | Kubernetes API server that you use to communicate with your cluster (using 8 | Kubernetes management tools such as kubectl). By default, this API server endpoint 9 | is public to the internet, and access to the API server is secured using a 10 | combination of AWS Identity and Access Management (IAM) and native Kubernetes Role 11 | Based Access Control (RBAC). 12 | 13 | 14 | ## Cluster Configuration / Updates 15 | - Create, Update or Delete a Cluster 16 | - Amazon EKS cluster endpoint access control(Endpoint public access or 17 | Endpoint private access) 18 | - Cluster Autoscaler 19 | - Control plane logging 20 | -------------------------------------------------------------------------------- /06_tools/03_kops/Makefile: -------------------------------------------------------------------------------- 1 | create_cluster: 2 | kops create cluster kops.jomo.click --zones us-east-1a,us-east-1b --state=s3://kops-jomo-click-state-store --yes 3 | 4 | validate_cluster: 5 | kops validate cluster kops.jomo.click --wait 10m 6 | 7 | delete_cluster: 8 | kops delete cluster kops.jomo.click --yes 9 | 10 | edit_cluster: 11 | kops edit cluster kops.jomo.click --state=s3://kops-jomo-click-state-store 12 | 13 | update_cluster: 14 | kops update cluster kops.jomo.click --state=s3://kops-jomo-click-state-store --yes 15 | 16 | rolling_cluster_update: 17 | kops rolling-update cluster kops.jomo.click --instance-group-roles=Master --force --yes 18 | 19 | list_clusters: 20 | kops get clusters 21 | 22 | set_context: 23 | kops export kubecfg kops.jomo.click 24 | 25 | tf: 26 | terraform apply 27 | 28 | aws_identity: 29 | aws sts get-caller-identity 30 | -------------------------------------------------------------------------------- /003_00_replica_sets_and_controllers/node-app/index.ts: -------------------------------------------------------------------------------- 1 | import { createServer, IncomingMessage, ServerResponse } from "http"; 2 | import { hostname } from "os"; 3 | 4 | const port = 3000; 5 | 6 | let counter = 0; 7 | const server = createServer((request: IncomingMessage, response: ServerResponse) => { 8 | switch (request.url) { 9 | case "/node-app": { 10 | if (request.method === "GET") { 11 | counter = counter + 1; 12 | if (counter % 4 === 0) { 13 | process.exit(1); 14 | } 15 | response.setHeader("Connection", "close"); 16 | response.end(`Hello world ${counter} from ${hostname()}, from app ${process.env.APP_NAME}`); 17 | } 18 | 19 | break; 20 | } 21 | default: { 22 | response.statusCode = 200; 23 | response.end("Unknown path"); 24 | } 25 | } 26 | }); 27 | 28 | server.listen(port); 29 | -------------------------------------------------------------------------------- /06_tools/007_alb_ingress/01_eks/k8s/ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: simple-ingress 5 | annotations: 6 | kubernetes.io/ingress.class: alb 7 | alb.ingress.kubernetes.io/scheme: internet-facing 8 | alb.ingress.kubernetes.io/target-type: instance 9 | spec: 10 | rules: 11 | - host: foo.jomo.click 12 | http: 13 | paths: 14 | - path: / 15 | pathType: Prefix 16 | backend: 17 | service: 18 | name: foo-app-service 19 | port: 20 | number: 3000 21 | - host: bar.jomo.click 22 | http: 23 | paths: 24 | - path: / 25 | pathType: Prefix 26 | backend: 27 | service: 28 | name: bar-app-service 29 | port: 30 | number: 3000 31 | -------------------------------------------------------------------------------- /06_tools/03_kops/deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: backend-deployment 5 | spec: 6 | replicas: 4 7 | selector: 8 | matchLabels: 9 | app: node-app 10 | template: 11 | metadata: 12 | labels: 13 | app: node-app 14 | spec: 15 | containers: 16 | - name: node-app 17 | image: robinnagpal/kubernetes-tutorial-003-node-app:latest 18 | 19 | #--- 20 | #apiVersion: v1 21 | #kind: Service 22 | #metadata: 23 | # name: node-app-service 24 | # annotations: 25 | # service.beta.kubernetes.io/aws-load-balancer-type: "nlb-ip" 26 | #spec: 27 | # type: LoadBalancer 28 | # selector: 29 | # app: node-app 30 | # ports: 31 | # - port: 80 32 | # targetPort: 3000 33 | # nodePort: 30464 34 | # sessionAffinity: None 35 | # sessionAffinityConfig: 36 | # clientIP: 37 | # timeoutSeconds: 1 38 | -------------------------------------------------------------------------------- /04_services/004_01_services/README.md: -------------------------------------------------------------------------------- 1 | ## Why services? 2 | * Pods are ephemeral 3 | * Pods is assigned ip after it has been assigned a node and before its started 4 | * Horizontal Scaling i.e. Multiple pods provide the same service 5 | 6 | ## What is service? 7 | Service is a single constant point of entry to a group of nodes providing the same service. 8 | 9 | e.g. image processing service 10 | 11 | ## Defining a Service 12 | 13 | 14 | ## Types of Services 15 | ### ClusterIP 16 | ### NodePort 17 | ### LoadBalancer 18 | ### ExternalName 19 | 20 | ## Service Discovery 21 | 22 | 23 | ## Services without pod selector 24 | * Pointing to another cluster or namespace 25 | * Pointing to external ip or domain 26 | * You are in the migration process 27 | 28 | ## Endpoint Object 29 | 30 | ## Other 31 | * Use names for port mappings 32 | * Kubernetes supports multiple port definitions on a Service object 33 | -------------------------------------------------------------------------------- /06_tools/04_eks/02_access_management_control/role_mappings/eks_developer.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: developer-clusterrole 5 | rules: 6 | - apiGroups: [""] 7 | resources: ["nodes", "namespaces", "pods"] 8 | verbs: ["get", "list"] 9 | - apiGroups: ["apps"] 10 | resources: ["deployments" ,"daemonsets" ,"statefulsets" ,"replicasets"] 11 | verbs: ["get", "list", "create"] 12 | - apiGroups: [ "batch"] 13 | resources: ["jobs"] 14 | verbs: ["get", "list"] 15 | --- 16 | apiVersion: rbac.authorization.k8s.io/v1 17 | kind: ClusterRoleBinding 18 | metadata: 19 | name: developer-clusterrole-binging 20 | subjects: 21 | - kind: User 22 | name: eks-developer 23 | apiGroup: rbac.authorization.k8s.io 24 | roleRef: 25 | kind: ClusterRole 26 | name: developer-clusterrole 27 | apiGroup: rbac.authorization.k8s.io 28 | -------------------------------------------------------------------------------- /06_tools/04_eks/02_access_management_control/Makefile: -------------------------------------------------------------------------------- 1 | create_cluster: 2 | eksctl create cluster -f cluster.yaml 3 | 4 | delete_cluster: 5 | eksctl delete cluster -f cluster.yaml 6 | 7 | create_nodegroup: 8 | eksctl create nodegroup --config-file=cluster.yaml 9 | 10 | delete_nodegroup: 11 | eksctl delete nodegroup --cluster=robin-personal-cluster --name=ng-2 12 | 13 | describe_cluster: 14 | eksctl utils describe-stacks --region=us-east-2 --cluster=robin-personal-cluster 15 | 16 | aws_identity: 17 | aws sts get-caller-identity 18 | 19 | set_context: 20 | eksctl utils write-kubeconfig --cluster=robin-personal-cluster --set-kubeconfig-context=true 21 | 22 | 23 | 24 | # ROLE RELATED 25 | 26 | set_aws_auth: 27 | kubectl apply -f aws_auth.yaml 28 | 29 | set_role_mappings: 30 | kubectl apply -f role_mappings/* 31 | 32 | export_aws_auth: 33 | kubectl get configmap aws-auth -n kube-system -o yaml > aws_auth.yaml 34 | -------------------------------------------------------------------------------- /06_tools/06_cert_manager/01_kops/Makefile: -------------------------------------------------------------------------------- 1 | create_cluster: 2 | kops create -f cluster.yaml 3 | kops create secret --name kops.jomo.click sshpublickey admin -i ~/.ssh/id_rsa.pub 4 | kops update cluster kops.jomo.click --yes 5 | kops export kubecfg kops.jomo.click --admin 6 | 7 | validate_cluster: 8 | kops validate cluster kops.jomo.click --wait 10m 9 | 10 | delete_cluster: 11 | kops delete cluster kops.jomo.click --yes 12 | 13 | edit_cluster: 14 | kops edit cluster kops.jomo.click --state=s3://kops-jomo-click-state-store 15 | 16 | update_cluster: 17 | kops update cluster kops.jomo.click --yes 18 | 19 | rolling_cluster_update: 20 | kops rolling-update cluster kops.jomo.click --instance-group-roles=Master --force --yes 21 | 22 | list_clusters: 23 | kops get clusters 24 | 25 | set_context: 26 | kops export kubecfg kops.jomo.click --admin 27 | 28 | tf: 29 | terraform apply 30 | 31 | aws_identity: 32 | aws sts get-caller-identity 33 | -------------------------------------------------------------------------------- /06_tools/05_haproxy_ingress/01_kops/Makefile: -------------------------------------------------------------------------------- 1 | create_cluster: 2 | kops create -f cluster.yaml 3 | kops create secret --name kops.jomo.click sshpublickey admin -i ~/.ssh/id_rsa.pub 4 | kops update cluster kops.jomo.click --yes 5 | kops export kubecfg kops.jomo.click --admin 6 | 7 | validate_cluster: 8 | kops validate cluster kops.jomo.click --wait 10m 9 | 10 | delete_cluster: 11 | kops delete cluster kops.jomo.click --yes 12 | 13 | edit_cluster: 14 | kops edit cluster kops.jomo.click --state=s3://kops-jomo-click-state-store 15 | 16 | update_cluster: 17 | kops update cluster kops.jomo.click --yes 18 | 19 | rolling_cluster_update: 20 | kops rolling-update cluster kops.jomo.click --instance-group-roles=Master --force --yes 21 | 22 | list_clusters: 23 | kops get clusters 24 | 25 | set_context: 26 | kops export kubecfg kops.jomo.click --admin 27 | 28 | tf: 29 | terraform apply 30 | 31 | aws_identity: 32 | aws sts get-caller-identity 33 | -------------------------------------------------------------------------------- /06_tools/05_haproxy_ingress/02_eks/Makefile: -------------------------------------------------------------------------------- 1 | create_cluster: 2 | kops create -f cluster.yaml 3 | kops create secret --name kops.jomo.click sshpublickey admin -i ~/.ssh/id_rsa.pub 4 | kops update cluster kops.jomo.click --yes 5 | kops export kubecfg kops.jomo.click --admin 6 | 7 | validate_cluster: 8 | kops validate cluster kops.jomo.click --wait 10m 9 | 10 | delete_cluster: 11 | kops delete cluster kops.jomo.click --yes 12 | 13 | edit_cluster: 14 | kops edit cluster kops.jomo.click --state=s3://kops-jomo-click-state-store 15 | 16 | update_cluster: 17 | kops update cluster kops.jomo.click --yes 18 | 19 | rolling_cluster_update: 20 | kops rolling-update cluster kops.jomo.click --instance-group-roles=Master --force --yes 21 | 22 | list_clusters: 23 | kops get clusters 24 | 25 | set_context: 26 | kops export kubecfg kops.jomo.click --admin 27 | 28 | tf: 29 | terraform apply 30 | 31 | aws_identity: 32 | aws sts get-caller-identity 33 | -------------------------------------------------------------------------------- /06_tools/04_eks/02_access_management_control/role_mappings/eks_trainee.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: trainee-clusterrole 5 | rules: 6 | - apiGroups: 7 | - "" 8 | resources: [ "*" ] 9 | verbs: 10 | - get 11 | - list 12 | - watch 13 | - apiGroups: 14 | - extensions 15 | resources: [ "*" ] 16 | verbs: 17 | - get 18 | - list 19 | - watch 20 | - apiGroups: 21 | - apps 22 | resources: [ "*" ] 23 | verbs: 24 | - get 25 | - list 26 | - watch 27 | 28 | --- 29 | apiVersion: rbac.authorization.k8s.io/v1 30 | kind: ClusterRoleBinding 31 | metadata: 32 | name: trainee-clusterrole-binging 33 | subjects: 34 | - kind: User 35 | name: eks-trainee 36 | apiGroup: rbac.authorization.k8s.io 37 | roleRef: 38 | kind: ClusterRole 39 | name: trainee-clusterrole 40 | apiGroup: rbac.authorization.k8s.io 41 | -------------------------------------------------------------------------------- /007_authentication_and_authorization/config-demo: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | clusters: 3 | - cluster: 4 | certificate-authority: fake-ca-file 5 | server: https://1.2.3.4 6 | name: development 7 | - cluster: 8 | insecure-skip-tls-verify: true 9 | server: https://5.6.7.8 10 | name: scratch 11 | contexts: 12 | - context: 13 | cluster: development 14 | namespace: frontend 15 | user: developer 16 | name: dev-frontend 17 | - context: 18 | cluster: development 19 | namespace: storage 20 | user: developer 21 | name: dev-storage 22 | - context: 23 | cluster: scratch 24 | namespace: default 25 | user: experimenter 26 | name: exp-scratch 27 | current-context: "" 28 | kind: Config 29 | preferences: {} 30 | users: 31 | - name: developer 32 | user: 33 | client-certificate: fake-cert-file 34 | client-key: fake-key-seefile 35 | - name: experimenter 36 | user: 37 | password: some-password 38 | username: exp 39 | -------------------------------------------------------------------------------- /06_tools/04_eks/kubernetes/configmaps/eks-console-full-access.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: eks-console-dashboard-full-access-clusterrole 5 | rules: 6 | - apiGroups: 7 | - "" 8 | resources: 9 | - nodes 10 | - namespaces 11 | - pods 12 | verbs: 13 | - get 14 | - list 15 | - apiGroups: 16 | - apps 17 | resources: 18 | - deployments 19 | - daemonsets 20 | - statefulsets 21 | - replicasets 22 | verbs: 23 | - get 24 | - list 25 | - apiGroups: 26 | - batch 27 | resources: 28 | - jobs 29 | verbs: 30 | - get 31 | - list 32 | --- 33 | apiVersion: rbac.authorization.k8s.io/v1 34 | kind: ClusterRoleBinding 35 | metadata: 36 | name: master-custom-binging 37 | subjects: 38 | - kind: User 39 | name: eks-console-dashboard-full-access 40 | apiGroup: rbac.authorization.k8s.io 41 | roleRef: 42 | kind: ClusterRole 43 | name: cluster-admin 44 | apiGroup: rbac.authorization.k8s.io 45 | -------------------------------------------------------------------------------- /06_tools/06_cert_manager/01_kops/k8s/cert-issues.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1 2 | kind: ClusterIssuer 3 | metadata: 4 | name: letsencrypt 5 | spec: 6 | acme: 7 | email: admin@jomo.click 8 | solvers: 9 | - dns01: 10 | route53: 11 | region: us-east-1 12 | role: arn:aws:iam::617960797257:role/cert_manager 13 | accessKeyID: AKIAY7YKVOREXDSO4VF2 14 | secretAccessKeySecretRef: 15 | name: k8s-user-credentials 16 | key: secret-access-key 17 | privateKeySecretRef: 18 | key: "" 19 | name: letsencrypt-production 20 | server: https://acme-v02.api.letsencrypt.org/directory 21 | --- 22 | apiVersion: cert-manager.io/v1 23 | kind: Certificate 24 | metadata: 25 | name: letsencrypt 26 | spec: 27 | commonName: jomo.click 28 | dnsNames: 29 | - jomo.click 30 | - foo.jomo.click 31 | - bar.jomo.click 32 | issuerRef: 33 | name: letsencrypt 34 | kind: ClusterIssuer 35 | secretName: tls-keys 36 | -------------------------------------------------------------------------------- /06_tools/04_eks/02_access_management_control/aws_auth.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: aws-auth 5 | namespace: kube-system 6 | data: 7 | mapRoles: | 8 | - groups: 9 | - system:bootstrappers 10 | - system:nodes 11 | rolearn: arn:aws:iam::00000000000:role/eksctl-robin-personal-cluster-nod-NodeInstanceRole-TUKH4Z187ANC 12 | username: system:node:{{EC2PrivateDNSName}} 13 | - groups: 14 | - system:bootstrappers 15 | - system:nodes 16 | rolearn: arn:aws:iam::00000000000:role/eksctl-robin-personal-cluster-nod-NodeInstanceRole-2RY0KK33CGIG 17 | username: system:node:{{EC2PrivateDNSName}} 18 | mapUsers: | 19 | - userarn: arn:aws:iam::00000000000:user/eks-trainee 20 | username: eks-trainee 21 | - userarn: arn:aws:iam::00000000000:user/eks-developer 22 | username: eks-developer 23 | - userarn: arn:aws:iam::00000000000:user/eks-super-admin 24 | groups: 25 | - system:masters 26 | username: eks-super-admin 27 | -------------------------------------------------------------------------------- /06_tools/007_alb_ingress/01_eks/rbac-role.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | labels: 6 | app.kubernetes.io/name: alb-ingress-controller 7 | name: alb-ingress-controller 8 | rules: 9 | - apiGroups: 10 | - "" 11 | - extensions 12 | resources: 13 | - configmaps 14 | - endpoints 15 | - events 16 | - ingresses 17 | - ingresses/status 18 | - services 19 | verbs: 20 | - create 21 | - get 22 | - list 23 | - update 24 | - watch 25 | - patch 26 | - apiGroups: 27 | - "" 28 | - extensions 29 | resources: 30 | - nodes 31 | - pods 32 | - secrets 33 | - services 34 | - namespaces 35 | verbs: 36 | - get 37 | - list 38 | - watch 39 | --- 40 | apiVersion: rbac.authorization.k8s.io/v1 41 | kind: ClusterRoleBinding 42 | metadata: 43 | labels: 44 | app.kubernetes.io/name: alb-ingress-controller 45 | name: alb-ingress-controller 46 | roleRef: 47 | apiGroup: rbac.authorization.k8s.io 48 | kind: ClusterRole 49 | name: alb-ingress-controller 50 | subjects: 51 | - kind: ServiceAccount 52 | name: alb-ingress-controller 53 | namespace: kube-system 54 | --- 55 | apiVersion: v1 56 | kind: ServiceAccount 57 | metadata: 58 | labels: 59 | app.kubernetes.io/name: alb-ingress-controller 60 | name: alb-ingress-controller 61 | namespace: kube-system 62 | ... 63 | -------------------------------------------------------------------------------- /003_01_probes/node-app/01_pod_definition.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: node-app-pod 5 | labels: 6 | app: node-app 7 | spec: 8 | containers: 9 | - name: node-app 10 | image: robinnagpal/kubernetes-tutorial-003-01-probes:latest 11 | imagePullPolicy: Always 12 | volumeMounts: 13 | - mountPath: /opt/probe_volume 14 | name: probe-volume 15 | livenessProbe: 16 | httpGet: 17 | port: 3000 18 | path: liveness 19 | initialDelaySeconds: 5 20 | failureThreshold: 2 21 | periodSeconds: 15 22 | startupProbe: 23 | httpGet: 24 | port: 3000 25 | path: startup 26 | initialDelaySeconds: 5 27 | failureThreshold: 2 28 | periodSeconds: 15 29 | readinessProbe: 30 | httpGet: 31 | port: 3000 32 | path: readiness 33 | initialDelaySeconds: 5 34 | failureThreshold: 2 35 | successThreshold: 2 36 | periodSeconds: 15 37 | 38 | volumes: 39 | - name: probe-volume 40 | hostPath: 41 | path: /probe_volume 42 | 43 | --- 44 | apiVersion: v1 45 | kind: Service 46 | metadata: 47 | name: node-app-service 48 | spec: 49 | type: LoadBalancer 50 | selector: 51 | app: node-app 52 | ports: 53 | - port: 80 54 | targetPort: 3000 55 | nodePort: 30464 56 | sessionAffinity: None 57 | sessionAffinityConfig: 58 | clientIP: 59 | timeoutSeconds: 1 60 | -------------------------------------------------------------------------------- /06_tools/007_alb_ingress/01_eks/Makefile: -------------------------------------------------------------------------------- 1 | create_cluster: 2 | eksctl create cluster -f cluster.yaml 3 | 4 | delete_cluster: 5 | eksctl delete cluster -f cluster.yaml 6 | 7 | describe_cluster: 8 | eksctl utils describe-stacks --region=us-east-2 --cluster=robin-personal-cluster 9 | 10 | aws_identity: 11 | aws sts get-caller-identity 12 | 13 | set_context: 14 | eksctl utils write-kubeconfig --cluster=robin-personal-cluster --set-kubeconfig-context=true 15 | 16 | enable_iam_sa_provider: 17 | eksctl utils associate-iam-oidc-provider --cluster=robin-personal-cluster --approve 18 | 19 | create_cluster_role: 20 | kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.4/docs/examples/rbac-role.yaml 21 | 22 | create_iam_policy: 23 | curl -o iam_policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.2.0/docs/install/iam_policy.json 24 | aws iam create-policy \ 25 | --policy-name AWSLoadBalancerControllerIAMPolicy \ 26 | --policy-document file://iam_policy.json 27 | 28 | create_service_account: 29 | eksctl create iamserviceaccount \ 30 | --cluster=robin-personal-cluster \ 31 | --namespace=kube-system \ 32 | --name=aws-load-balancer-controller \ 33 | --attach-policy-arn=arn:aws:iam::617960797257:policy/AWSLoadBalancerControllerIAMPolicy \ 34 | --override-existing-serviceaccounts \ 35 | --approve 36 | 37 | deploy_cert_manager: 38 | kubectl apply \ 39 | --validate=false \ 40 | -f https://github.com/jetstack/cert-manager/releases/download/v1.1.1/cert-manager.yaml 41 | 42 | deploy_ingress_controller: 43 | kubectl apply -f v2_2_0_full.yaml 44 | 45 | deploy_application: 46 | kustomize build ./k8s | kubectl apply -f - 47 | 48 | delete_application: 49 | kustomize build ./k8s | kubectl delete -f - 50 | 51 | -------------------------------------------------------------------------------- /003_01_probes/volumes/events.txt: -------------------------------------------------------------------------------- 1 | Events: 2 | Type Reason Age From Message 3 | ---- ------ ---- ---- ------- 4 | Normal Scheduled 2m45s default-scheduler Successfully assigned default/node-app-pod to minikube 5 | Normal Pulled 2m29s kubelet Successfully pulled image "robinnagpal/kubernetes-tutorial-003-01-probes:latest" in 15.522543474s 6 | Normal Pulled 85s kubelet Successfully pulled image "robinnagpal/kubernetes-tutorial-003-01-probes:latest" in 898.742558ms 7 | Normal Killing 14s (x2 over 86s) kubelet Container node-app failed startup probe, will be restarted 8 | Normal Pulling 14s (x3 over 2m45s) kubelet Pulling image "robinnagpal/kubernetes-tutorial-003-01-probes:latest" 9 | Normal Created 13s (x3 over 2m29s) kubelet Created container node-app 10 | Normal Started 13s (x3 over 2m29s) kubelet Started container node-app 11 | Normal Pulled 13s kubelet Successfully pulled image "robinnagpal/kubernetes-tutorial-003-01-probes:latest" in 993.657498ms 12 | Warning Unhealthy 8s (x5 over 2m23s) kubelet Startup probe failed: HTTP probe failed with statuscode: 500 13 | Normal Killing 29s (x3 over 2m49s) kubelet Container node-app failed startup probe, will be restarted 14 | Normal Pulling 29s (x4 over 4m8s) kubelet Pulling image "robinnagpal/kubernetes-tutorial-003-01-probes:latest" 15 | Normal Created 28s (x4 over 3m52s) kubelet Created container node-app 16 | Normal Started 28s (x4 over 3m52s) kubelet Started container node-app 17 | Normal Pulled 28s kubelet Successfully pulled image "robinnagpal/kubernetes-tutorial-003-01-probes:latest" in 973.237924ms 18 | -------------------------------------------------------------------------------- /003_00_replica_sets_and_controllers/README.md: -------------------------------------------------------------------------------- 1 | ## Unmanaged Pod 2 | * Created when we directly create a pod 3 | * If the pod errors out and dies, the pod is restarted by Kubernetes 4 | * Kubelet which runs in a node takes care of this 5 | * If the node dies, the unmanaged pods running in the node are lost. 6 | 7 | ## What is Kubelet? 8 | The kubelet is the primary "node agent" that runs on each node. 9 | 10 | The kubelet takes a set of PodSpecs that are provided through various mechanisms 11 | (primarily through the apiserver) and ensures that the containers described in those 12 | PodSpecs are running and healthy. The kubelet doesn't manage containers which were 13 | not created by Kubernetes. 14 | 15 | 16 | 17 | ## Replication Controller 18 | If the node fails, when pods are manages by Replication Controllers, 19 | the pods are created in another healthy node. Replication Controller 20 | makes sure the number of running pods match the replica count mentioned 21 | in Replication Controller. 22 | 23 | Relplication Controller chooses the pods based on label selectors 24 | 25 | 26 | ## Three parts of Replication Controller 27 | * Label Selector 28 | * Replica Count 29 | * Pod Template 30 | 31 | # Changing label selector of Replication Controller 32 | * TRY AND SEE WHAT HAPPENS 33 | 34 | 35 | ## Other 36 | * Pod isn't tied to Replication Controller, but it does contain the reference 37 | to replication controller in `metadata.ownerReferences` field. This can be 38 | used for debugging. 39 | 40 | * Delete Replication Controller and not deleting the pods can be achieved by 41 | `--cascade=false` 42 | 43 | ## Replication Sets 44 | 45 | ## Replication Sets vs Replication Containers 46 | Replication sets provide more flexibility for selection of pods. Replication 47 | Controllers only allow selection by certain label, Replica Set's selector allows 48 | mathching pods that lack certain label or that include a certain label key. 49 | 50 | Replication Contoller can match at just one label, not multiple 51 | 52 | ## Show above in exercise 53 | 54 | ## Replica Sets Label Selectors 55 | 1) In 56 | 2) NotIn 57 | 3) Exists 58 | 4) DoesNotExist 59 | -------------------------------------------------------------------------------- /01_intro/001_1_docker_vs_kubernetes/README.md: -------------------------------------------------------------------------------- 1 | Docker vs Kubernetes || Apple vs Apple Pie 2 | 3 | # First things first 4 | It's never docker vs kubernetes, its mostly docker and Kubernetes. Both of them work at different levels. 5 | 6 | Apple vs Apple Pie 7 | Right question can be "Apple Pie vs Blueberry Pie" or "Apple vs Blueberry" 8 | Since apple is an ingredient of apple pie, they both are at different levels 9 | 10 | Docker -> Containers -> Apple 11 | Kubernetes -> Container orchestration and management software -> Apple Pie 12 | 13 | Like we have Apple in Apple pie, we similarly use docker in Kubernetes 14 | 15 | Of course there can be different type of fruits, similarly there can be different container runtimes 16 | like docker and other is rktlet(rkt) 17 | 18 | And there can be many type of pies, similarly there can be different container management and orchestration softwares 19 | like Kubernetes and other is Docker Swarm 20 | 21 | 22 | Let's recap 23 | --- If you like the video give it thumbs up and press the subscribe button 24 | 25 | * Application contains different application modules 26 | - Frontend 27 | - Backend Server 28 | - Database 29 | You create containers for all these. This is like your apples 30 | * To be able to deploy your app, you need other things like 31 | - Load balancing 32 | - Monitoring 33 | - Scaling 34 | - Storage 35 | This is like needing other ingredients like flour, sugar 36 | 37 | * You put this all together and it becomes a production ready app. You put this all together and deploy it to Kubernetes 38 | Some of the things here you get free in Kubernetes like 39 | - Load balancing 40 | - Monitoring 41 | - Scaling 42 | You have to buy certain things like servers where Kubernetes runs, storage for which you can use any cloud provider like AWS, Google, Azure, DigitalOcean 43 | 44 | Similarly, putting all the things together you get apple pie. There are somethings in your kitchen already like Flour, Sugar. 45 | But you might have to grocery store to buy things like Vanilla Extract. 46 | 47 | - So 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /06_tools/04_eks/02_access_management_control/README.md: -------------------------------------------------------------------------------- 1 | # Video URL 2 | https://www.youtube.com/watch?v=cB0fCMPIj1Y 3 | 4 | # aws-auth 5 | 6 | **Refer to aws_auth.yaml file** 7 | ```yaml 8 | apiVersion: v1 9 | kind: ConfigMap 10 | metadata: 11 | name: aws-auth 12 | namespace: kube-system 13 | data: 14 | mapRoles: | 15 | - groups: 16 | - system:bootstrappers 17 | - system:nodes 18 | rolearn: arn:aws:iam::00000000000:role/eksctl-robin-personal-cluster-nod-NodeInstanceRole-TUKH4Z187ANC 19 | username: system:node:{{EC2PrivateDNSName}} 20 | - groups: 21 | - system:bootstrappers 22 | - system:nodes 23 | rolearn: arn:aws:iam::00000000000:role/eksctl-robin-personal-cluster-nod-NodeInstanceRole-2RY0KK33CGIG 24 | username: system:node:{{EC2PrivateDNSName}} 25 | mapUsers: | 26 | - userarn: arn:aws:iam::00000000000:user/eks-trainee 27 | username: eks-trainee 28 | - userarn: arn:aws:iam::00000000000:user/eks-developer 29 | username: eks-developer 30 | - userarn: arn:aws:iam::00000000000:user/eks-super-admin 31 | groups: 32 | - system:masters 33 | username: eks-super-admin 34 | ``` 35 | 36 | # Role and Role Bindings 37 | **Refer to role_mappings folder** 38 | 39 | 40 | ```yaml 41 | apiVersion: rbac.authorization.k8s.io/v1 42 | kind: ClusterRole 43 | metadata: 44 | name: developer-clusterrole 45 | rules: 46 | - apiGroups: [""] 47 | resources: ["nodes", "namespaces", "pods"] 48 | verbs: ["get", "list"] 49 | - apiGroups: ["apps"] 50 | resources: ["deployments" ,"daemonsets" ,"statefulsets" ,"replicasets"] 51 | verbs: ["get", "list", "create"] 52 | - apiGroups: [ "batch"] 53 | resources: ["jobs"] 54 | verbs: ["get", "list"] 55 | --- 56 | apiVersion: rbac.authorization.k8s.io/v1 57 | kind: ClusterRoleBinding 58 | metadata: 59 | name: developer-clusterrole-binging 60 | subjects: 61 | - kind: User 62 | name: eks-developer 63 | apiGroup: rbac.authorization.k8s.io 64 | roleRef: 65 | kind: ClusterRole 66 | name: developer-clusterrole 67 | apiGroup: rbac.authorization.k8s.io 68 | 69 | ``` 70 | 71 | # References 72 | https://docs.aws.amazon.com/eks/latest/userguide/add-user-role.html 73 | https://github.com/kubernetes-sigs/aws-iam-authenticator#how-does-it-work 74 | https://www.youtube.com/watch?v=WvnXemaYQ50 75 | -------------------------------------------------------------------------------- /06_tools/eks_vs_kops/EKS_vs_KOPS.md: -------------------------------------------------------------------------------- 1 | # EKS 2 | * EKS automates most of the steps and allows you to get an EKS instance up and running in minutes by bringing up the 3 | Kubernetes control plane (masters), assuming you already have your AWS IAM permissions and users configured correctly. 4 | * EKS does not create nodes automatically when you create an instance, so you have to do that manually. 5 | 6 | 7 | # KOPS 8 | * Kops, on the other hand, lets you actually configure masters and nodes yourself. Yes, it works with AWS, but master 9 | nodes are created as EC2 instances instead. The tool also supports automation during the setup process. 10 | * You can update the kops templates at any time and it will take care of making the proper changes in AWS. 11 | The kube infrastructure with kops is described through templates, so, you simply describe the desired state and kops 12 | will work to match the kube environment to that. 13 | 14 | 15 | # EKS vs KOPS 16 | ## Cluster Management 17 | * With EKS, things such as managing the master node and configuring the cloud environment are handled by Amazon, leaving 18 | you with little to no control over them. 19 | * Kops, on the other hand, lets you configure your cloud environments the way you like them, including configuring them 20 | to meet specific needs. Kops’s manual approach means you are completely responsible for making sure that the cluster 21 | is configured correctly and running properly. You are also responsible for keeping the master nodes up to date and 22 | working properly. 23 | 24 | ## Access Management and control 25 | * Speaking of control and access management, by default, kops uses a secret (API bearer token) to authenticate users 26 | but it has also added support for configuring authentication systems. Since Kops 1.10, the tool also supports AWS 27 | IAM Authenticator (which is the way EKS authenticates). As mentioned before, EKS relies on IAM for authenticating 28 | users and the authorization is done by Kubernetes RBAC in the standard way. 29 | 30 | ## Networking 31 | * EKS uses the VPC CNI (network plugin) which gives each pod a VPC IP address and enables any pod to be able to 32 | communicate with other AWS services without issues. 33 | 34 | * Kops doesn’t have these advantages natively. To fully benefit from your use of kops, you need additional tools that 35 | offer these functionalities. Also, kops uses private networking for pods by default and supports several CNIs for 36 | pod networking, but AWS VPC CNI is not listed there. 37 | 38 | 39 | -------------------------------------------------------------------------------- /003_01_probes/README.md: -------------------------------------------------------------------------------- 1 | # Three Types 2 | - Liveness 3 | - Readiness 4 | - Startup 5 | 6 | # Liveness 7 | The kubelet uses liveness probes to know when to restart a container. For example, liveness probes could catch a deadlock, 8 | where an application is running, but unable to make progress. Restarting a container in such a state can help to make 9 | the application more available despite bugs 10 | 11 | # Readiness 12 | The kubelet uses readiness probes to know when a container is ready to start accepting traffic. A Pod is considered ready 13 | when all of its containers are ready. One use of this signal is to control which Pods are used as backends for Services. 14 | When a Pod is not ready, it is removed from Service load balancers. 15 | 16 | # Startup 17 | The kubelet uses startup probes to know when a container application has started. If such a probe is configured, it disables 18 | liveness and readiness checks until it succeeds, making sure those probes don't interfere with the application startup. This 19 | can be used to adopt liveness checks on slow starting containers, avoiding them getting killed by the kubelet before they are 20 | up and running. 21 | 22 | # Use Cases 23 | - Want to make sure there is no dead locks in the application and its always running 24 | - use liveness probe 25 | - If the application is temporarily down, and you don't want to serve traffic. Eg connectivity 26 | issues with Database 27 | - add readiness probe as you don't want to restart the application, because that will be of no use 28 | - When the startup time is slow 29 | - add startup 30 | 31 | 32 | # Configure Probes 33 | Probes have a number of fields that you can use to more precisely control the behavior of liveness and readiness checks: 34 | 35 | * initialDelaySeconds: Number of seconds after the container has started before liveness or readiness probes are initiated. 36 | Defaults to 0 seconds. Minimum value is 0. 37 | * periodSeconds: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. 38 | * timeoutSeconds: Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. 39 | * successThreshold: Minimum consecutive successes for the probe to be considered successful after having failed. 40 | Defaults to 1. Must be 1 for liveness and startup Probes. Minimum value is 1. 41 | * failureThreshold: When a probe fails, Kubernetes will try failureThreshold times before giving up. 42 | Giving up in case of liveness probe means restarting the container. In case of readiness probe the Pod will be marked 43 | Unready. Defaults to 3. Minimum value is 1. 44 | 45 | -------------------------------------------------------------------------------- /003_01_probes/node-app/index.ts: -------------------------------------------------------------------------------- 1 | import { createServer, IncomingMessage, ServerResponse } from "http"; 2 | import { appendFileSync, readFileSync, writeFileSync } from "fs"; 3 | 4 | const port = 3000; 5 | 6 | const log = (message: string): void => { 7 | console.log(message); 8 | appendFileSync("/opt/probe_volume/logs.txt", message); 9 | }; 10 | 11 | const readCounter = (): number => { 12 | const counterValue = readFileSync("/opt/probe_volume/counter.txt"); 13 | return parseInt(counterValue.toString()); 14 | }; 15 | 16 | const writeCounter = (counter: number): void => { 17 | writeFileSync("/opt/probe_volume/counter.txt", counter.toString(10)); 18 | }; 19 | 20 | const respondBack = (probeName: string, counter: number, response: ServerResponse): void => { 21 | const message = `${probeName} called`; 22 | const decorated = `${new Date().toString()} - ${message} . Counter - ${counter} \n \n`; 23 | log(decorated); 24 | response.setHeader("Connection", "close"); 25 | response.end(decorated); 26 | }; 27 | 28 | const notFound = (response: ServerResponse, counter: number): void => { 29 | response.statusCode = 404; 30 | log("Unknown path"); 31 | response.end("Unknown path"); 32 | }; 33 | 34 | const notReady = (probeName: string, counter: number, response: ServerResponse): void => { 35 | response.statusCode = 500; 36 | const decorated = `${new Date().toString()} - ${probeName} Not ready . Counter - ${counter} \n \n`; 37 | log(decorated); 38 | response.end("Not Ready"); 39 | }; 40 | 41 | const server = createServer((request: IncomingMessage, response: ServerResponse) => { 42 | const counter = readCounter(); 43 | writeCounter(counter + 1); 44 | try { 45 | if (request.method === "GET") { 46 | switch (request.url) { 47 | case "/node-app": { 48 | respondBack("node-app", counter, response); 49 | break; 50 | } 51 | case "/liveness": { 52 | if (counter > 20) { 53 | respondBack("Liveness", counter, response); 54 | } else { 55 | notReady("Liveness", counter, response); 56 | } 57 | 58 | break; 59 | } 60 | case "/readiness": { 61 | if (counter > 30) { 62 | respondBack("Readiness", counter, response); 63 | } else { 64 | notReady("Readiness", counter, response); 65 | } 66 | break; 67 | } 68 | case "/startup": { 69 | if (counter > 7) { 70 | respondBack("Startup", counter, response); 71 | } else { 72 | notReady("Startup", counter, response); 73 | } 74 | break; 75 | } 76 | default: { 77 | notFound(response, counter); 78 | } 79 | } 80 | } else { 81 | notFound(response, counter); 82 | } 83 | } catch (e) { 84 | console.log(e); 85 | } 86 | }); 87 | 88 | server.listen(port); 89 | -------------------------------------------------------------------------------- /06_tools/06_cert_manager/01_kops/main.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | aws = { 4 | source = "hashicorp/aws" 5 | version = "~> 3.0" 6 | } 7 | } 8 | 9 | backend "s3" { 10 | bucket = "kubernetes-learnings-robin-nagpal" 11 | key = "terraform-state/kubernetes-tutorials/06_tools/03_kops" 12 | region = "us-east-1" 13 | } 14 | 15 | } 16 | 17 | provider "aws" { 18 | region = "us-east-1" 19 | } 20 | 21 | variable "environment" { 22 | default = "prod" 23 | } 24 | 25 | data "aws_caller_identity" "iam" {} 26 | 27 | data "aws_iam_user" "kubernetes_cluster_user" { 28 | user_name = "kubernetes_cluster_user" 29 | } 30 | 31 | resource "aws_iam_role" "cert_manager" { 32 | name = "cert_manager" 33 | assume_role_policy = jsonencode({ 34 | Version = "2012-10-17" 35 | Statement = [ 36 | { 37 | Action = "sts:AssumeRole" 38 | Effect = "Allow" 39 | Sid = "" 40 | Principal = { 41 | AWS = "arn:aws:iam::${data.aws_caller_identity.iam.account_id}:root" 42 | } 43 | }, 44 | ] 45 | }) 46 | } 47 | 48 | data "aws_iam_policy_document" "cert_manager_policy_doc" { 49 | statement { 50 | effect = "Allow" 51 | actions = ["route53:GetChange"] 52 | resources = ["arn:aws:route53:::change/*"] 53 | } 54 | statement { 55 | effect = "Allow" 56 | actions = [ 57 | "route53:ChangeResourceRecordSets", 58 | "route53:ListResourceRecordSets" 59 | ] 60 | resources = [ 61 | "arn:aws:route53:::hostedzone/*"] 62 | } 63 | statement { 64 | effect = "Allow" 65 | actions = ["route53:ListHostedZonesByName"] 66 | resources = [ "*"] 67 | } 68 | 69 | } 70 | 71 | resource "aws_iam_policy" "cert_manager_policy" { 72 | name = "cert_manager_policy_document" 73 | policy = data.aws_iam_policy_document.cert_manager_policy_doc.json 74 | } 75 | resource "aws_iam_role_policy_attachment" "cert_manager_policy_attachment" { 76 | policy_arn = aws_iam_policy.cert_manager_policy.arn 77 | role = aws_iam_role.cert_manager.id 78 | } 79 | 80 | 81 | data "aws_iam_policy_document" "cert_manager_assume_role_policy" { 82 | statement { 83 | actions = [ 84 | "sts:AssumeRole", 85 | ] 86 | resources = [ 87 | aws_iam_role.cert_manager.arn 88 | ] 89 | sid = "AllowAssumingOfRole" 90 | } 91 | } 92 | 93 | resource "aws_iam_policy" "cert_manager_assume_role_policy" { 94 | name = "cert_manager_role_assume_policy_document" 95 | policy = data.aws_iam_policy_document.cert_manager_assume_role_policy.json 96 | } 97 | 98 | resource "aws_iam_user_policy_attachment" "kubernetes_cluster_user_cert_manager_assume" { 99 | policy_arn = aws_iam_policy.cert_manager_assume_role_policy.arn 100 | user = data.aws_iam_user.kubernetes_cluster_user.user_name 101 | } 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /007_authentication_and_authorization/README.md: -------------------------------------------------------------------------------- 1 | ## Access to multiple servers 2 | https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/ 3 | 4 | * You can quickly switch between clusters by using the `kubectl config use-context` command. 5 | or `kubectl config --kubeconfig=config-demo use-context dev-frontend` 6 | * Each context is a triple (cluster, user, namespace). 7 | 8 | 9 | ## Commands 10 | * To view config 11 | `kubectl config view` or `kubectl config --kubeconfig=config-demo view` 12 | * To just view current cotext 13 | `kubectl config view --minify` or `kubectl config --kubeconfig=config-demo view --minify` 14 | * Using multiple kube configs 15 | `export KUBECONFIG=$KUBECONFIG:config-demo:config-demo-2` 16 | 17 | ## Authentication 18 | https://kubernetes.io/docs/reference/access-authn-authz/authentication/ 19 | 20 | All Kubernetes clusters have two categories of users: 21 | 1) service accounts managed by Kubernetes 22 | 2) normal users. 23 | 24 | It is assumed that a cluster-independent service manages normal users in the following ways: 25 | - an administrator distributing private keys 26 | - a user store like Keystone or Google Accounts 27 | - a file with a list of usernames and passwords 28 | 29 | ### Normal Users 30 | Kubernetes does not have objects which represent normal user accounts. 31 | Normal users cannot be added to a cluster through an API call. 32 | 33 | Even though a normal user cannot be added via an API call, any user that presents a valid certificate 34 | signed by the cluster's certificate authority (CA) is considered authenticated. 35 | 36 | In this configuration, Kubernetes determines the username from the common name field in the 37 | 'subject' of the cert (e.g., "/CN=bob"). From there, the role based access control (RBAC) sub-system would 38 | determine whether the user is authorized to perform a specific operation on a resource 39 | 40 | ### Service Accounts 41 | service accounts are users managed by the Kubernetes API. They are bound to specific namespaces, and created 42 | automatically by the API server or manually through API calls 43 | 44 | ## Normal User Authentication 45 | A few steps are required in order to get a normal user to be able to authenticate and invoke an API. First, this user 46 | must have certificate issued by the Kubernetes cluster, and then present that Certificate to the API call as the 47 | Certificate Header or through the kubectl. 48 | 49 | 50 | 51 | 52 | ## Authorization 53 | https://kubernetes.io/docs/reference/access-authn-authz/authorization/ 54 | 55 | ## References 56 | ### Certificate authority 57 | https://www.ssl.com/faqs/what-is-a-certificate-authority/ 58 | 59 | ### EKS Authorization 60 | https://caylent.com/eks-authentication-authorization 61 | https://github.com/kubernetes-sigs/aws-iam-authenticator#full-configuration-format 62 | https://docs.aws.amazon.com/eks/latest/userguide/add-user-role.html 63 | -------------------------------------------------------------------------------- /02_pods/002_0_pods/README.md: -------------------------------------------------------------------------------- 1 | # What are Pods 2 | Pod is a "co-located" group of containers abd represents a basic building block in Kubernetes. We don't 3 | deploy containers individually, we always deploy pods of container/s 4 | 5 | # Why do we need Pods 6 | ## One vs Multiple Containers 7 | * Containers are designed to run only a single process per container 8 | * Disadvantages of running multiple processes in a container 9 | * You have to manage processes your self 10 | * If all processes write to standard output, it then difficult to separate the logs 11 | * Difficult to add logic to restart if one of the process dies 12 | 13 | 14 | # Two individual containers vs two containers in a Pod 15 | 16 | ## Two individual containers 17 | * Port mappings ad added to the host machine which makes it difficult to replicate since the post mappings 18 | need to be unique for each replica 19 | 20 | ## Two containers in a Pod 21 | * Pods help provide the two containers running in the same Pod the 22 | same env as if they are running in the same pod . ??? 23 | * Containers are partially isolated 24 | * Containers in a pod share the same Linux Namespace instead of each container having its own 25 | * Kubernetes achieves this by configuring Docker to not create separate namespaces 26 | * Containers run under the same Network and UTS namespace i.e. that share the same hostname 27 | * Containers run under the same IPC namespace and can communicate through IPC 28 | * Containers in the same Pod can also share the same PID namespace 29 | * Port mappings are done to the pod making it easy to create replicas of the pods 30 | * File systems of each container is isolated from the filesystem of other containers in the pod 31 | Questions 32 | - Do containers don't have separate namespace when running in pods? 33 | 34 | # Pod Networking 35 | When pod is create 36 | * It gets its own namespace 37 | * It gets its own virtual ethernet connection( --- does this refer to IP?) 38 | 39 | A pod is like a host as it has IP address and a range of ports that it can be mapped to container pods. 40 | IP of the pod is reachable from all other pods in k8s cluster 41 | 42 | # When do you need multiple containers 43 | * Backups 44 | * Synchronizer 45 | * Authentication Gateway 46 | * Collecting and pushing the logs 47 | 48 | 49 | # Connecting to Pod 50 | * Using k8s port forward 51 | `kubectl port-forward kubia-manual 8888:8080` 52 | * Using services 53 | 54 | 55 | # Using labels to organize pods 56 | * Organizing pods and all other Kubernetes objects is done through labels 57 | * ----- Show Kubernetes Pod file ------- 58 | * Listing pods with labels `kubectl get po -l app=admin-ui` 59 | 60 | # Stopping and removing pods 61 | * Delete by name - `kubectl pod delete nginx` 62 | * Delete by label - `kubectl pod delete po -l env=dev` 63 | 64 | 65 | 66 | Other Networking Concepts 67 | * Every pod has an IP address 68 | * 69 | https://unix.stackexchange.com/a/183722 70 | -------------------------------------------------------------------------------- /003_01_probes/node-app/README.md: -------------------------------------------------------------------------------- 1 | # What are Pods 2 | Pod is a "co-located" group of containers abd represents a basic building block in Kubernetes. We don't 3 | deploy containers individually, we always deploy pods of container/s 4 | 5 | # Why do we need Pods 6 | ## One vs Multiple Containers 7 | * Containers are designed to run only a single process per container 8 | * Disadvantages of running multiple processes in a container 9 | * You have to manage processes your self 10 | * If all processes write to standard output, it then difficult to separate the logs 11 | * Difficult to add logic to restart if one of the process dies 12 | 13 | 14 | # Two individual containers vs two containers in a Pod 15 | 16 | ## Two individual containers 17 | * Port mappings ad added to the host machine which makes it difficult to replicate since the post mappings 18 | need to be unique for each replica 19 | 20 | ## Two containers in a Pod 21 | * Pods help provide the two containers running in the same Pod the 22 | same env as if they are running in the same pod . ??? 23 | * Containers are partially isolated 24 | * Containers in a pod share the same Linux Namespace instead of each container having its own 25 | * Kubernetes achieves this by configuring Docker to not create separate namespaces 26 | * Containers run under the same Network and UTS namespace i.e. that share the same hostname 27 | * Containers run under the same IPC namespace and can communicate through IPC 28 | * Containers in the same Pod can also share the same PID namespace 29 | * Port mappings are done to the pod making it easy to create replicas of the pods 30 | * File systems of each container is isolated from the filesystem of other containers in the pod 31 | Questions 32 | - Do containers don't have separate namespace when running in pods? 33 | 34 | # Pod Networking 35 | When pod is create 36 | * It gets its own namespace 37 | * It gets its own virtual ethernet connection( --- does this refer to IP?) 38 | 39 | A pod is like a host as it has IP address and a range of ports that it can be mapped to container pods. 40 | IP of the pod is reachable from all other pods in k8s cluster 41 | 42 | # When do you need multiple containers 43 | * Backups 44 | * Synchronizer 45 | * Authentication Gateway 46 | * Collecting and pushing the logs 47 | 48 | 49 | # Connecting to Pod 50 | * Using k8s port forward 51 | `kubectl port-forward kubia-manual 8888:8080` 52 | * Using services 53 | 54 | 55 | # Using labels to organize pods 56 | * Organizing pods and all other Kubernetes objects is done through labels 57 | * ----- Show Kubernetes Pod file ------- 58 | * Listing pods with labels `kubectl get po -l app=admin-ui` 59 | 60 | # Stopping and removing pods 61 | * Delete by name - `kubectl pod delete nginx` 62 | * Delete by label - `kubectl pod delete po -l env=dev` 63 | 64 | 65 | 66 | Other Networking Concepts 67 | * Every pod has an IP address 68 | * 69 | https://unix.stackexchange.com/a/183722 70 | -------------------------------------------------------------------------------- /06_tools/06_cert_manager/01_kops/cluster.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kops.k8s.io/v1alpha2 2 | kind: Cluster 3 | metadata: 4 | creationTimestamp: null 5 | name: kops.jomo.click 6 | spec: 7 | api: 8 | loadBalancer: 9 | class: Network 10 | type: Public 11 | awsLoadBalancerController: 12 | enabled: true 13 | certManager: 14 | enabled: true 15 | # defaultIssuer: SelfSigned 16 | authorization: 17 | rbac: {} 18 | channel: stable 19 | cloudProvider: aws 20 | configBase: s3://kops-jomo-click-state-store/kops.jomo.click 21 | containerRuntime: containerd 22 | etcdClusters: 23 | - cpuRequest: 200m 24 | etcdMembers: 25 | - encryptedVolume: true 26 | instanceGroup: master-us-east-1a 27 | name: a 28 | memoryRequest: 100Mi 29 | name: main 30 | - cpuRequest: 100m 31 | etcdMembers: 32 | - encryptedVolume: true 33 | instanceGroup: master-us-east-1a 34 | name: a 35 | memoryRequest: 100Mi 36 | name: events 37 | iam: 38 | allowContainerRegistry: true 39 | legacy: false 40 | kubelet: 41 | anonymousAuth: false 42 | kubernetesApiAccess: 43 | - 0.0.0.0/0 44 | kubernetesVersion: 1.20.6 45 | masterPublicName: api.kops.jomo.click 46 | networkCIDR: 172.20.0.0/16 47 | networking: 48 | kubenet: {} 49 | nonMasqueradeCIDR: 100.64.0.0/10 50 | sshAccess: 51 | - 0.0.0.0/0 52 | subnets: 53 | - cidr: 172.20.32.0/19 54 | name: us-east-1a 55 | type: Public 56 | zone: us-east-1a 57 | - cidr: 172.20.64.0/19 58 | name: us-east-1b 59 | type: Public 60 | zone: us-east-1b 61 | topology: 62 | dns: 63 | type: Public 64 | masters: public 65 | nodes: public 66 | 67 | --- 68 | 69 | apiVersion: kops.k8s.io/v1alpha2 70 | kind: InstanceGroup 71 | metadata: 72 | creationTimestamp: null 73 | labels: 74 | kops.k8s.io/cluster: kops.jomo.click 75 | name: master-us-east-1a 76 | spec: 77 | image: 099720109477/ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-20210415 78 | machineType: t3.medium 79 | maxSize: 1 80 | minSize: 1 81 | nodeLabels: 82 | kops.k8s.io/instancegroup: master-us-east-1a 83 | role: Master 84 | subnets: 85 | - us-east-1a 86 | 87 | --- 88 | 89 | apiVersion: kops.k8s.io/v1alpha2 90 | kind: InstanceGroup 91 | metadata: 92 | creationTimestamp: null 93 | labels: 94 | kops.k8s.io/cluster: kops.jomo.click 95 | name: nodes-us-east-1a 96 | spec: 97 | image: 099720109477/ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-20210415 98 | machineType: t3.medium 99 | maxSize: 1 100 | minSize: 1 101 | nodeLabels: 102 | kops.k8s.io/instancegroup: nodes-us-east-1a 103 | role: Node 104 | subnets: 105 | - us-east-1a 106 | 107 | --- 108 | 109 | apiVersion: kops.k8s.io/v1alpha2 110 | kind: InstanceGroup 111 | metadata: 112 | creationTimestamp: null 113 | labels: 114 | kops.k8s.io/cluster: kops.jomo.click 115 | name: nodes-us-east-1b 116 | spec: 117 | image: 099720109477/ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-20210415 118 | machineType: t3.medium 119 | maxSize: 1 120 | minSize: 1 121 | nodeLabels: 122 | kops.k8s.io/instancegroup: nodes-us-east-1b 123 | role: Node 124 | subnets: 125 | - us-east-1b 126 | -------------------------------------------------------------------------------- /06_tools/05_haproxy_ingress/01_kops/cluster.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kops.k8s.io/v1alpha2 2 | kind: Cluster 3 | metadata: 4 | creationTimestamp: null 5 | name: kops.jomo.click 6 | spec: 7 | api: 8 | loadBalancer: 9 | class: Network 10 | type: Public 11 | awsLoadBalancerController: 12 | enabled: true 13 | certManager: 14 | enabled: true 15 | defaultIssuer: SelfSigned 16 | authorization: 17 | rbac: {} 18 | channel: stable 19 | cloudProvider: aws 20 | configBase: s3://kops-jomo-click-state-store/kops.jomo.click 21 | containerRuntime: containerd 22 | etcdClusters: 23 | - cpuRequest: 200m 24 | etcdMembers: 25 | - encryptedVolume: true 26 | instanceGroup: master-us-east-1a 27 | name: a 28 | memoryRequest: 100Mi 29 | name: main 30 | - cpuRequest: 100m 31 | etcdMembers: 32 | - encryptedVolume: true 33 | instanceGroup: master-us-east-1a 34 | name: a 35 | memoryRequest: 100Mi 36 | name: events 37 | iam: 38 | allowContainerRegistry: true 39 | legacy: false 40 | kubelet: 41 | anonymousAuth: false 42 | kubernetesApiAccess: 43 | - 0.0.0.0/0 44 | kubernetesVersion: 1.20.6 45 | masterPublicName: api.kops.jomo.click 46 | networkCIDR: 172.20.0.0/16 47 | networking: 48 | kubenet: {} 49 | nonMasqueradeCIDR: 100.64.0.0/10 50 | sshAccess: 51 | - 0.0.0.0/0 52 | subnets: 53 | - cidr: 172.20.32.0/19 54 | name: us-east-1a 55 | type: Public 56 | zone: us-east-1a 57 | - cidr: 172.20.64.0/19 58 | name: us-east-1b 59 | type: Public 60 | zone: us-east-1b 61 | topology: 62 | dns: 63 | type: Public 64 | masters: public 65 | nodes: public 66 | 67 | --- 68 | 69 | apiVersion: kops.k8s.io/v1alpha2 70 | kind: InstanceGroup 71 | metadata: 72 | creationTimestamp: null 73 | labels: 74 | kops.k8s.io/cluster: kops.jomo.click 75 | name: master-us-east-1a 76 | spec: 77 | image: 099720109477/ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-20210415 78 | machineType: t3.medium 79 | maxSize: 1 80 | minSize: 1 81 | nodeLabels: 82 | kops.k8s.io/instancegroup: master-us-east-1a 83 | role: Master 84 | subnets: 85 | - us-east-1a 86 | 87 | --- 88 | 89 | apiVersion: kops.k8s.io/v1alpha2 90 | kind: InstanceGroup 91 | metadata: 92 | creationTimestamp: null 93 | labels: 94 | kops.k8s.io/cluster: kops.jomo.click 95 | name: nodes-us-east-1a 96 | spec: 97 | image: 099720109477/ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-20210415 98 | machineType: t3.medium 99 | maxSize: 1 100 | minSize: 1 101 | nodeLabels: 102 | kops.k8s.io/instancegroup: nodes-us-east-1a 103 | role: Node 104 | subnets: 105 | - us-east-1a 106 | 107 | --- 108 | 109 | apiVersion: kops.k8s.io/v1alpha2 110 | kind: InstanceGroup 111 | metadata: 112 | creationTimestamp: null 113 | labels: 114 | kops.k8s.io/cluster: kops.jomo.click 115 | name: nodes-us-east-1b 116 | spec: 117 | image: 099720109477/ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-20210415 118 | machineType: t3.medium 119 | maxSize: 1 120 | minSize: 1 121 | nodeLabels: 122 | kops.k8s.io/instancegroup: nodes-us-east-1b 123 | role: Node 124 | subnets: 125 | - us-east-1b 126 | -------------------------------------------------------------------------------- /06_tools/05_haproxy_ingress/02_eks/cluster.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kops.k8s.io/v1alpha2 2 | kind: Cluster 3 | metadata: 4 | creationTimestamp: null 5 | name: kops.jomo.click 6 | spec: 7 | api: 8 | loadBalancer: 9 | class: Network 10 | type: Public 11 | awsLoadBalancerController: 12 | enabled: true 13 | certManager: 14 | enabled: true 15 | defaultIssuer: SelfSigned 16 | authorization: 17 | rbac: {} 18 | channel: stable 19 | cloudProvider: aws 20 | configBase: s3://kops-jomo-click-state-store/kops.jomo.click 21 | containerRuntime: containerd 22 | etcdClusters: 23 | - cpuRequest: 200m 24 | etcdMembers: 25 | - encryptedVolume: true 26 | instanceGroup: master-us-east-1a 27 | name: a 28 | memoryRequest: 100Mi 29 | name: main 30 | - cpuRequest: 100m 31 | etcdMembers: 32 | - encryptedVolume: true 33 | instanceGroup: master-us-east-1a 34 | name: a 35 | memoryRequest: 100Mi 36 | name: events 37 | iam: 38 | allowContainerRegistry: true 39 | legacy: false 40 | kubelet: 41 | anonymousAuth: false 42 | kubernetesApiAccess: 43 | - 0.0.0.0/0 44 | kubernetesVersion: 1.20.6 45 | masterPublicName: api.kops.jomo.click 46 | networkCIDR: 172.20.0.0/16 47 | networking: 48 | kubenet: {} 49 | nonMasqueradeCIDR: 100.64.0.0/10 50 | sshAccess: 51 | - 0.0.0.0/0 52 | subnets: 53 | - cidr: 172.20.32.0/19 54 | name: us-east-1a 55 | type: Public 56 | zone: us-east-1a 57 | - cidr: 172.20.64.0/19 58 | name: us-east-1b 59 | type: Public 60 | zone: us-east-1b 61 | topology: 62 | dns: 63 | type: Public 64 | masters: public 65 | nodes: public 66 | 67 | --- 68 | 69 | apiVersion: kops.k8s.io/v1alpha2 70 | kind: InstanceGroup 71 | metadata: 72 | creationTimestamp: null 73 | labels: 74 | kops.k8s.io/cluster: kops.jomo.click 75 | name: master-us-east-1a 76 | spec: 77 | image: 099720109477/ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-20210415 78 | machineType: t3.medium 79 | maxSize: 1 80 | minSize: 1 81 | nodeLabels: 82 | kops.k8s.io/instancegroup: master-us-east-1a 83 | role: Master 84 | subnets: 85 | - us-east-1a 86 | 87 | --- 88 | 89 | apiVersion: kops.k8s.io/v1alpha2 90 | kind: InstanceGroup 91 | metadata: 92 | creationTimestamp: null 93 | labels: 94 | kops.k8s.io/cluster: kops.jomo.click 95 | name: nodes-us-east-1a 96 | spec: 97 | image: 099720109477/ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-20210415 98 | machineType: t3.medium 99 | maxSize: 1 100 | minSize: 1 101 | nodeLabels: 102 | kops.k8s.io/instancegroup: nodes-us-east-1a 103 | role: Node 104 | subnets: 105 | - us-east-1a 106 | 107 | --- 108 | 109 | apiVersion: kops.k8s.io/v1alpha2 110 | kind: InstanceGroup 111 | metadata: 112 | creationTimestamp: null 113 | labels: 114 | kops.k8s.io/cluster: kops.jomo.click 115 | name: nodes-us-east-1b 116 | spec: 117 | image: 099720109477/ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-20210415 118 | machineType: t3.medium 119 | maxSize: 1 120 | minSize: 1 121 | nodeLabels: 122 | kops.k8s.io/instancegroup: nodes-us-east-1b 123 | role: Node 124 | subnets: 125 | - us-east-1b 126 | -------------------------------------------------------------------------------- /01_intro/001_0_intro/README.md: -------------------------------------------------------------------------------- 1 | # Kubernetes Intro 2 | Kubernetes is one of the essential technologies to lean in 2020 or 2021. Kubernetes is essential 3 | skills of not just every DevOps Engineers, but every backend developer or manager 4 | should know at least the basics of Kubernetes. 5 | 6 | # Introduction 7 | We will cover the following things in this blogpost 8 | * Kubernetes high level intro 9 | * Kubernetes hello world 10 | * Kubernetes concepts 11 | * Pods 12 | * Services 13 | * Deployments 14 | * Other important things 15 | * Volumes 16 | * ConfigMaps and Secrets 17 | 18 | 19 | Let's first look at a simple kubernetes example to understand the power of Kubernetes 20 | 21 | # Kubernetes high level intro 22 | In modern day apps to deploy a software application following steps are needed 23 | 1) Writing of the code/logic 24 | 2) Continuous integration to unit test the application code 25 | 3) Packaging the code 26 | 4) Running the code on server 27 | 28 | Since apps have to manage quite some dependencies, the most reliable way to package and run the app 29 | is using container. Docker is industry wide standard these days. 30 | 31 | To orchestrate containers we need a software or a framework and Kubernetes is the most widely used 32 | container orchestration technology that is used these days. 33 | 34 | Things like creating replicas, load balancing requests, doing incremental deployments, adding health checks, 35 | managing configurations and secrets can all be done in Kubernetes in a few lines of code 36 | 37 | # Kubernetes hello world 38 | In this example we create a simple node js server which increments a counter 39 | every time it gets a request and returns the response of the format `Hello world <> from <>` 40 | Here counter reflects the number of requests received by the server and hostname is the hostname on which 41 | the process is running. 42 | 43 | Some other details to note are 44 | 1. We set the header `response.setHeader("Connection", "close")` which makes sure that the connection 45 | is closed by browser after it get's the response 46 | 2. We build the app using docker and tag it using the command `docker build . -t robinnagpal/kubernetes-tutorial-001-node-app` 47 | 3. We then push this to docker repository 48 | 49 | Deploy to Kubernetes 50 | 1. We now are going to use this app and run 5 replicas or copies in parallel 51 | 2. We are going to load balance these using a service in a round robin manner 52 | 3. We then expose it to the outside world 53 | 54 | When we now send requests from our browser we see that everytime it hits a different container 55 | 56 | # Understanding what is involved 57 | As we said earlier, there are primary four steps involved in developing and deploying the applications 58 | 1) Step 1 - Application Development - Here we use NodeJS to write a simple application which replies back to HTTP requests 59 | 2) Step 2 - Continuous Integration - We skipped this part to keep things simple 60 | 3) Step 3 - Packaging Application - We have docker here. Dockerfile within the directory tells how to package the app. 61 | This is how the docker file looks like 62 | 63 | ```dockerfile 64 | FROM node:12 65 | 66 | COPY . . 67 | WORKDIR . 68 | 69 | RUN npm install 70 | ENTRYPOINT ["npm", "start"] 71 | ``` 72 | 73 | We use this docker file to build an image 74 | -------------------------------------------------------------------------------- /02_pods/002_0_pods/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@types/node": { 8 | "version": "14.14.10", 9 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.10.tgz", 10 | "integrity": "sha512-J32dgx2hw8vXrSbu4ZlVhn1Nm3GbeCFNw2FWL8S5QKucHGY0cyNwjdQdO+KMBZ4wpmC7KhLCiNsdk1RFRIYUQQ==", 11 | "dev": true 12 | }, 13 | "arg": { 14 | "version": "4.1.3", 15 | "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", 16 | "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" 17 | }, 18 | "buffer-from": { 19 | "version": "1.1.1", 20 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 21 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" 22 | }, 23 | "diff": { 24 | "version": "4.0.2", 25 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", 26 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" 27 | }, 28 | "make-error": { 29 | "version": "1.3.6", 30 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", 31 | "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" 32 | }, 33 | "prettier": { 34 | "version": "2.2.1", 35 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", 36 | "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==" 37 | }, 38 | "source-map": { 39 | "version": "0.6.1", 40 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 41 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" 42 | }, 43 | "source-map-support": { 44 | "version": "0.5.19", 45 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", 46 | "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", 47 | "requires": { 48 | "buffer-from": "^1.0.0", 49 | "source-map": "^0.6.0" 50 | } 51 | }, 52 | "ts-node": { 53 | "version": "9.0.0", 54 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.0.0.tgz", 55 | "integrity": "sha512-/TqB4SnererCDR/vb4S/QvSZvzQMJN8daAslg7MeaiHvD8rDZsSfXmNeNumyZZzMned72Xoq/isQljYSt8Ynfg==", 56 | "requires": { 57 | "arg": "^4.1.0", 58 | "diff": "^4.0.1", 59 | "make-error": "^1.1.1", 60 | "source-map-support": "^0.5.17", 61 | "yn": "3.1.1" 62 | } 63 | }, 64 | "typescript": { 65 | "version": "4.1.2", 66 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.2.tgz", 67 | "integrity": "sha512-thGloWsGH3SOxv1SoY7QojKi0tc+8FnOmiarEGMbd/lar7QOEd3hvlx3Fp5y6FlDUGl9L+pd4n2e+oToGMmhRQ==" 68 | }, 69 | "yn": { 70 | "version": "3.1.1", 71 | "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", 72 | "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /01_intro/001_0_intro/node-app/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@types/node": { 8 | "version": "14.14.8", 9 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.8.tgz", 10 | "integrity": "sha512-z/5Yd59dCKI5kbxauAJgw6dLPzW+TNOItNE00PkpzNwUIEwdj/Lsqwq94H5DdYBX7C13aRA0CY32BK76+neEUA==", 11 | "dev": true 12 | }, 13 | "arg": { 14 | "version": "4.1.3", 15 | "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", 16 | "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" 17 | }, 18 | "buffer-from": { 19 | "version": "1.1.1", 20 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 21 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" 22 | }, 23 | "diff": { 24 | "version": "4.0.2", 25 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", 26 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" 27 | }, 28 | "make-error": { 29 | "version": "1.3.6", 30 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", 31 | "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" 32 | }, 33 | "prettier": { 34 | "version": "2.1.2", 35 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.2.tgz", 36 | "integrity": "sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==" 37 | }, 38 | "source-map": { 39 | "version": "0.6.1", 40 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 41 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" 42 | }, 43 | "source-map-support": { 44 | "version": "0.5.19", 45 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", 46 | "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", 47 | "requires": { 48 | "buffer-from": "^1.0.0", 49 | "source-map": "^0.6.0" 50 | } 51 | }, 52 | "ts-node": { 53 | "version": "9.0.0", 54 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.0.0.tgz", 55 | "integrity": "sha512-/TqB4SnererCDR/vb4S/QvSZvzQMJN8daAslg7MeaiHvD8rDZsSfXmNeNumyZZzMned72Xoq/isQljYSt8Ynfg==", 56 | "requires": { 57 | "arg": "^4.1.0", 58 | "diff": "^4.0.1", 59 | "make-error": "^1.1.1", 60 | "source-map-support": "^0.5.17", 61 | "yn": "3.1.1" 62 | } 63 | }, 64 | "typescript": { 65 | "version": "4.0.5", 66 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.5.tgz", 67 | "integrity": "sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ==" 68 | }, 69 | "yn": { 70 | "version": "3.1.1", 71 | "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", 72 | "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /003_00_replica_sets_and_controllers/node-app/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@types/node": { 8 | "version": "14.14.8", 9 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.8.tgz", 10 | "integrity": "sha512-z/5Yd59dCKI5kbxauAJgw6dLPzW+TNOItNE00PkpzNwUIEwdj/Lsqwq94H5DdYBX7C13aRA0CY32BK76+neEUA==", 11 | "dev": true 12 | }, 13 | "arg": { 14 | "version": "4.1.3", 15 | "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", 16 | "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" 17 | }, 18 | "buffer-from": { 19 | "version": "1.1.1", 20 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 21 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" 22 | }, 23 | "diff": { 24 | "version": "4.0.2", 25 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", 26 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" 27 | }, 28 | "make-error": { 29 | "version": "1.3.6", 30 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", 31 | "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" 32 | }, 33 | "prettier": { 34 | "version": "2.1.2", 35 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.2.tgz", 36 | "integrity": "sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==" 37 | }, 38 | "source-map": { 39 | "version": "0.6.1", 40 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 41 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" 42 | }, 43 | "source-map-support": { 44 | "version": "0.5.19", 45 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", 46 | "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", 47 | "requires": { 48 | "buffer-from": "^1.0.0", 49 | "source-map": "^0.6.0" 50 | } 51 | }, 52 | "ts-node": { 53 | "version": "9.0.0", 54 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.0.0.tgz", 55 | "integrity": "sha512-/TqB4SnererCDR/vb4S/QvSZvzQMJN8daAslg7MeaiHvD8rDZsSfXmNeNumyZZzMned72Xoq/isQljYSt8Ynfg==", 56 | "requires": { 57 | "arg": "^4.1.0", 58 | "diff": "^4.0.1", 59 | "make-error": "^1.1.1", 60 | "source-map-support": "^0.5.17", 61 | "yn": "3.1.1" 62 | } 63 | }, 64 | "typescript": { 65 | "version": "4.0.5", 66 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.5.tgz", 67 | "integrity": "sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ==" 68 | }, 69 | "yn": { 70 | "version": "3.1.1", 71 | "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", 72 | "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /06_tools/03_kops/main.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | aws = { 4 | source = "hashicorp/aws" 5 | version = "~> 3.0" 6 | } 7 | } 8 | 9 | backend "s3" { 10 | bucket = "kubernetes-learnings-robin-nagpal" 11 | key = "terraform-state/kubernetes-tutorials/06_tools/03_kops" 12 | region = "us-east-1" 13 | } 14 | 15 | } 16 | 17 | provider "aws" { 18 | region = "us-east-1" 19 | } 20 | 21 | data "aws_caller_identity" "iam" {} 22 | 23 | variable "environment" { 24 | default = "prod" 25 | } 26 | 27 | 28 | variable "readonly_users" { 29 | description = "readonly_users" 30 | default = [ 31 | "readonly_user1", 32 | "readonly_user2", 33 | "readonly_user3" 34 | ] 35 | } 36 | 37 | variable "developers" { 38 | description = "developers" 39 | default = [ 40 | "developers1", 41 | "developers2", 42 | "developers3" 43 | ] 44 | } 45 | 46 | resource "aws_iam_user" readonly_users { 47 | for_each = toset(var.readonly_users) 48 | name = "tf-test-${each.key}" 49 | } 50 | 51 | resource "aws_iam_user" developers { 52 | for_each = toset(var.developers) 53 | name = "tf-test-${each.key}" 54 | } 55 | 56 | resource "aws_iam_group" "tf-test-readonly_users" { 57 | name = "tf-test-readonly-users" 58 | } 59 | resource "aws_iam_group" "tf-test-developers" { 60 | name = "tf-test-developers" 61 | } 62 | 63 | resource "aws_iam_group_membership" "tf-test-readonly_users-membership" { 64 | group = aws_iam_group.tf-test-readonly_users.name 65 | name = "tf-test-readonly-users-membership" 66 | users = toset([for k in aws_iam_user.readonly_users : k.name]) 67 | } 68 | 69 | resource "aws_iam_group_membership" "tf-test-developers-membership" { 70 | group = aws_iam_group.tf-test-developers.name 71 | name = "tf-test-developers-membership" 72 | users = toset([for k in aws_iam_user.developers : k.name]) 73 | } 74 | 75 | resource "aws_iam_role" "kubernetes_readonly_user_role" { 76 | name = "kubernetes_readonly_users_role" 77 | assume_role_policy = jsonencode({ 78 | Version = "2012-10-17" 79 | Statement = [ 80 | { 81 | Action = "sts:AssumeRole" 82 | Effect = "Allow" 83 | Sid = "" 84 | Principal = { 85 | AWS = "arn:aws:iam::${data.aws_caller_identity.iam.account_id}:root" 86 | } 87 | }, 88 | ] 89 | }) 90 | } 91 | 92 | resource "aws_iam_role" "kubernetes_developer" { 93 | name = "kubernetes_developer_role" 94 | assume_role_policy = jsonencode({ 95 | Version = "2012-10-17" 96 | Statement = [ 97 | { 98 | Action = "sts:AssumeRole" 99 | Effect = "Allow" 100 | Sid = "" 101 | Principal = { 102 | AWS = "arn:aws:iam::${data.aws_caller_identity.iam.account_id}:root" 103 | } 104 | }, 105 | ] 106 | }) 107 | } 108 | 109 | 110 | data "aws_iam_policy_document" "group_assume_readonly_user_role_policy" { 111 | statement { 112 | actions = [ 113 | "sts:AssumeRole", 114 | ] 115 | resources = [ 116 | aws_iam_role.kubernetes_readonly_user_role.arn 117 | ] 118 | sid = "AllowAssumingOfRole" 119 | } 120 | } 121 | 122 | 123 | data "aws_iam_policy_document" "group_assume_developer_role_policy" { 124 | statement { 125 | actions = [ 126 | "sts:AssumeRole", 127 | ] 128 | resources = [ 129 | aws_iam_role.kubernetes_developer.arn 130 | ] 131 | sid = "AllowAssumingOfRole" 132 | } 133 | } 134 | 135 | resource "aws_iam_group_policy" "readonly_user_group_policy" { 136 | group = aws_iam_group.tf-test-readonly_users.id 137 | name = "kubernetes_readonly_user_role_access" 138 | policy = data.aws_iam_policy_document.group_assume_readonly_user_role_policy.json 139 | } 140 | 141 | 142 | resource "aws_iam_group_policy" "developer_group_policy" { 143 | group = aws_iam_group.tf-test-developers.id 144 | name = "kubernetes_developer_role_access" 145 | policy = data.aws_iam_policy_document.group_assume_developer_role_policy.json 146 | } 147 | -------------------------------------------------------------------------------- /04_services/004_02_services_internals/README.md: -------------------------------------------------------------------------------- 1 | # Resources 2 | ### Using Source IP 3 | https://kubernetes.io/docs/tutorials/services/source-ip/ 4 | 5 | 6 | ## Service IP Address 7 | * All non-headless services have ClusterIp assigned to them 8 | * ClusterIps are handed out form a pool of available ip addresses 9 | * ApiServer handles the process of assigning ClusterIp to the service. After assigning the ip, ApiServer tells 10 | the kubelet process about IPs as assigned to what services as well as the endpoints which back these services 11 | 12 | ## NAT (Network Address Translation) 13 | https://www.youtube.com/watch?v=QBqPzHEDzvo 14 | - Public ipv4 address are limited 15 | - Our internet provider allocates a public ip for the router 16 | - All the devices on the home network share the same public ip address, but have their own private 17 | ip address 18 | - Private ip address have range 192.168.x.x, 10.x.x.x, or 172.16.0.0 - 172.31.255.255 19 | - NAT translates the private ip to public(source to destination) and public to private(destination to source) 20 | - NAT forwarding table contains list of internal ip address mappings which is used for IP translations 21 | 22 | ## Source NAT 23 | Source NAT changes the source address in IP header of a packet. It may also change the source port in 24 | the TCP/UDP headers. The typical usage is to change a private (rfc1918) address/port into a public 25 | address/port for packets leaving your network. 26 | 27 | In K8S service terms it means "replacing the source IP on a packet; in this page, that usually means 28 | replacing with the IP address of a node." 29 | 30 | ## Destination NAT 31 | Destination NAT changes the destination address in IP header of a packet. It may also change the 32 | destination port in the TCP/UDP headers.The typical usage of this is to redirect incoming packets 33 | with a destination of a public address/port to a private IP address/port inside your network. 34 | 35 | In K8S terms it means "replacing the destination IP on a packet; in this page, that usually means 36 | replacing with the IP address of a Pod" 37 | 38 | ## Virtual IPs 39 | https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies 40 | A virtual IP address, such as the one assigned to every Service in Kubernetes 41 | 42 | Every node in a Kubernetes cluster runs a kube-proxy. kube-proxy is responsible for implementing a form of 43 | virtual IP for Services of type other than ExternalName. 44 | 45 | ## kube-proxy 46 | https://www.youtube.com/watch?v=nKKTdo2Yo6Y 47 | * a network daemon that orchestrates Service VIP management on every node 48 | * It watches all the services and endpoints 49 | * It applies some filters like ignores the headless services 50 | * It links the end points with services 51 | * Combines endpoint and service information and update te rules on the node 52 | 53 | 54 | 55 | https://stackoverflow.com/a/36088688/440432 56 | 57 | ### Kube Proxy - Userspace mode 58 | Description 59 | * It is responsible for watching each service and endpoint object associated with each object 60 | and configure a proxier. 61 | * When client is trying to access the service using the Virtual IP, the proxier is responsible 62 | for sending the traffic to actual pods 63 | * Client connects to Kube-Proxy via iptable rules and then kube-proxy does the actual load balancing 64 | to the pods 65 | * 66 | --- 67 | 68 | ### Kube Proxy - iptables 69 | * In iptables mode we still us iptables, but here the traffic is not proxies via kube proxy, it is directly 70 | sent from iptables to the backend nodes 71 | * Kube-proxy will hook into pre-routing and output chain 72 | * It will add a new chain called "KUBE-SERVICES" 73 | * It will identity the service and will send to the appropriate service chain 74 | * The more services you have, the more service chains you will have. With more services, your iptable 75 | configuration will become complex 76 | * In each service chain you will have one rule corresponding to each backend 77 | * These rules for each backend are probability rules, and are used to send the traffic to the 78 | backends randomly 79 | * Finally, you have a chain for each endpoint of the service and it is used doing the DNAT i.e. 80 | replacing the service VIP with pod ip 81 | * 82 | 83 | ### Kube proxy - ipvs 84 | 85 | 86 | ### Kube proxy - core DNS 87 | ## iptables 88 | http://linux-training.be/networking/ch14.html#:~:text=The%20nat%20table%20in%20iptables,they%20exit%20the%20OUTPUT%20chain. 89 | 90 | ## Endpoint 91 | A simplified view of all the ips(of pods) backing a given service 92 | 93 | ## 94 | 95 | Other Description 96 | * Kublet runs on every node 97 | * Kublet checks the health status of each pod and sends this information to API Server 98 | * Endpoint Controller, keeps track of all the pods and services, and it will update the Endpoint 99 | object of all the services based on all the pods matching a given label 100 | 101 | 102 | ## Data plane vs Control plane 103 | 104 | 105 | # Other Vidoes 106 | 107 | https://www.youtube.com/watch?v=BxDnv7MpJ0I 108 | 109 | https://www.youtube.com/watch?v=H5Zl_kDOwBU 110 | 111 | https://www.youtube.com/watch?v=InZVNuKY5GY 112 | 113 | Very good basics video 114 | https://www.youtube.com/watch?v=InZVNuKY5GY 115 | 116 | 117 | # iptables -L -n -t nat 118 | -------------------------------------------------------------------------------- /06_tools/05_haproxy_ingress/02_eks/k8s/haproxy-ingress-controller.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: haproxy-controller 6 | 7 | --- 8 | apiVersion: v1 9 | kind: ServiceAccount 10 | metadata: 11 | name: haproxy-ingress-service-account 12 | namespace: haproxy-controller 13 | 14 | --- 15 | kind: ClusterRole 16 | apiVersion: rbac.authorization.k8s.io/v1 17 | metadata: 18 | name: haproxy-ingress-cluster-role 19 | rules: 20 | - apiGroups: 21 | - "" 22 | resources: 23 | - configmaps 24 | - endpoints 25 | - nodes 26 | - pods 27 | - services 28 | - namespaces 29 | - events 30 | - serviceaccounts 31 | verbs: 32 | - get 33 | - list 34 | - watch 35 | - apiGroups: 36 | - "extensions" 37 | - "networking.k8s.io" 38 | resources: 39 | - ingresses 40 | - ingresses/status 41 | - ingressclasses 42 | verbs: 43 | - get 44 | - list 45 | - watch 46 | - apiGroups: 47 | - "extensions" 48 | - "networking.k8s.io" 49 | resources: 50 | - ingresses/status 51 | verbs: 52 | - update 53 | - apiGroups: 54 | - "" 55 | resources: 56 | - secrets 57 | verbs: 58 | - get 59 | - list 60 | - watch 61 | - create 62 | - patch 63 | - update 64 | 65 | --- 66 | kind: ClusterRoleBinding 67 | apiVersion: rbac.authorization.k8s.io/v1 68 | metadata: 69 | name: haproxy-ingress-cluster-role-binding 70 | namespace: haproxy-controller 71 | roleRef: 72 | apiGroup: rbac.authorization.k8s.io 73 | kind: ClusterRole 74 | name: haproxy-ingress-cluster-role 75 | subjects: 76 | - kind: ServiceAccount 77 | name: haproxy-ingress-service-account 78 | namespace: haproxy-controller 79 | 80 | --- 81 | apiVersion: v1 82 | kind: ConfigMap 83 | metadata: 84 | name: haproxy 85 | namespace: haproxy-controller 86 | data: 87 | syslog-server: "address:stdout, format: raw, facility:daemon, level:debug" 88 | --- 89 | apiVersion: apps/v1 90 | kind: Deployment 91 | metadata: 92 | labels: 93 | run: ingress-default-backend 94 | name: ingress-default-backend 95 | namespace: haproxy-controller 96 | spec: 97 | replicas: 1 98 | selector: 99 | matchLabels: 100 | run: ingress-default-backend 101 | template: 102 | metadata: 103 | labels: 104 | run: ingress-default-backend 105 | spec: 106 | containers: 107 | - name: ingress-default-backend 108 | image: gcr.io/google_containers/defaultbackend:1.0 109 | ports: 110 | - containerPort: 8080 111 | 112 | --- 113 | apiVersion: v1 114 | kind: Service 115 | metadata: 116 | labels: 117 | run: ingress-default-backend 118 | name: ingress-default-backend 119 | namespace: haproxy-controller 120 | spec: 121 | selector: 122 | run: ingress-default-backend 123 | ports: 124 | - name: port-1 125 | port: 8080 126 | protocol: TCP 127 | targetPort: 8080 128 | 129 | --- 130 | apiVersion: apps/v1 131 | kind: Deployment 132 | metadata: 133 | labels: 134 | run: haproxy-ingress 135 | name: haproxy-ingress 136 | namespace: haproxy-controller 137 | spec: 138 | replicas: 1 139 | selector: 140 | matchLabels: 141 | run: haproxy-ingress 142 | template: 143 | metadata: 144 | labels: 145 | run: haproxy-ingress 146 | spec: 147 | serviceAccountName: haproxy-ingress-service-account 148 | containers: 149 | - name: haproxy-ingress 150 | image: haproxytech/kubernetes-ingress 151 | args: 152 | - --configmap=haproxy-controller/haproxy 153 | - --default-backend-service=haproxy-controller/ingress-default-backend 154 | securityContext: 155 | runAsUser: 1000 156 | runAsGroup: 1000 157 | capabilities: 158 | drop: 159 | - ALL 160 | add: 161 | - NET_BIND_SERVICE 162 | resources: 163 | requests: 164 | cpu: "500m" 165 | memory: "50Mi" 166 | livenessProbe: 167 | httpGet: 168 | path: /healthz 169 | port: 1042 170 | ports: 171 | - name: http 172 | containerPort: 80 173 | - name: https 174 | containerPort: 443 175 | - name: stat 176 | containerPort: 1024 177 | env: 178 | - name: TZ 179 | value: "Etc/UTC" 180 | - name: POD_NAME 181 | valueFrom: 182 | fieldRef: 183 | fieldPath: metadata.name 184 | - name: POD_NAMESPACE 185 | valueFrom: 186 | fieldRef: 187 | fieldPath: metadata.namespace 188 | initContainers: 189 | - name: sysctl 190 | image: busybox:musl 191 | command: 192 | - /bin/sh 193 | - -c 194 | - sysctl -w net.ipv4.ip_unprivileged_port_start=0 195 | securityContext: 196 | privileged: true 197 | --- 198 | apiVersion: v1 199 | kind: Service 200 | metadata: 201 | labels: 202 | run: haproxy-ingress 203 | name: haproxy-ingress 204 | namespace: haproxy-controller 205 | annotations: 206 | service.beta.kubernetes.io/aws-load-balancer-type: "nlb" 207 | spec: 208 | selector: 209 | run: haproxy-ingress 210 | type: LoadBalancer 211 | ports: 212 | - name: http 213 | port: 80 214 | protocol: TCP 215 | targetPort: 80 216 | - name: https 217 | port: 443 218 | protocol: TCP 219 | targetPort: 443 220 | - name: stat 221 | port: 1024 222 | protocol: TCP 223 | targetPort: 1024 224 | -------------------------------------------------------------------------------- /06_tools/05_haproxy_ingress/01_kops/k8s/haproxy-ingress-controller.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: haproxy-controller 6 | 7 | --- 8 | apiVersion: v1 9 | kind: ServiceAccount 10 | metadata: 11 | name: haproxy-ingress-service-account 12 | namespace: haproxy-controller 13 | 14 | --- 15 | kind: ClusterRole 16 | apiVersion: rbac.authorization.k8s.io/v1 17 | metadata: 18 | name: haproxy-ingress-cluster-role 19 | rules: 20 | - apiGroups: 21 | - "" 22 | resources: 23 | - configmaps 24 | - endpoints 25 | - nodes 26 | - pods 27 | - services 28 | - namespaces 29 | - events 30 | - serviceaccounts 31 | verbs: 32 | - get 33 | - list 34 | - watch 35 | - apiGroups: 36 | - "extensions" 37 | - "networking.k8s.io" 38 | resources: 39 | - ingresses 40 | - ingresses/status 41 | - ingressclasses 42 | verbs: 43 | - get 44 | - list 45 | - watch 46 | - apiGroups: 47 | - "extensions" 48 | - "networking.k8s.io" 49 | resources: 50 | - ingresses/status 51 | verbs: 52 | - update 53 | - apiGroups: 54 | - "" 55 | resources: 56 | - secrets 57 | verbs: 58 | - get 59 | - list 60 | - watch 61 | - create 62 | - patch 63 | - update 64 | 65 | --- 66 | kind: ClusterRoleBinding 67 | apiVersion: rbac.authorization.k8s.io/v1 68 | metadata: 69 | name: haproxy-ingress-cluster-role-binding 70 | namespace: haproxy-controller 71 | roleRef: 72 | apiGroup: rbac.authorization.k8s.io 73 | kind: ClusterRole 74 | name: haproxy-ingress-cluster-role 75 | subjects: 76 | - kind: ServiceAccount 77 | name: haproxy-ingress-service-account 78 | namespace: haproxy-controller 79 | 80 | --- 81 | apiVersion: v1 82 | kind: ConfigMap 83 | metadata: 84 | name: haproxy 85 | namespace: haproxy-controller 86 | data: 87 | syslog-server: "address:stdout, format: raw, facility:daemon, level:debug" 88 | --- 89 | apiVersion: apps/v1 90 | kind: Deployment 91 | metadata: 92 | labels: 93 | run: ingress-default-backend 94 | name: ingress-default-backend 95 | namespace: haproxy-controller 96 | spec: 97 | replicas: 1 98 | selector: 99 | matchLabels: 100 | run: ingress-default-backend 101 | template: 102 | metadata: 103 | labels: 104 | run: ingress-default-backend 105 | spec: 106 | containers: 107 | - name: ingress-default-backend 108 | image: gcr.io/google_containers/defaultbackend:1.0 109 | ports: 110 | - containerPort: 8080 111 | 112 | --- 113 | apiVersion: v1 114 | kind: Service 115 | metadata: 116 | labels: 117 | run: ingress-default-backend 118 | name: ingress-default-backend 119 | namespace: haproxy-controller 120 | spec: 121 | selector: 122 | run: ingress-default-backend 123 | ports: 124 | - name: port-1 125 | port: 8080 126 | protocol: TCP 127 | targetPort: 8080 128 | 129 | --- 130 | apiVersion: apps/v1 131 | kind: Deployment 132 | metadata: 133 | labels: 134 | run: haproxy-ingress 135 | name: haproxy-ingress 136 | namespace: haproxy-controller 137 | spec: 138 | replicas: 1 139 | selector: 140 | matchLabels: 141 | run: haproxy-ingress 142 | template: 143 | metadata: 144 | labels: 145 | run: haproxy-ingress 146 | spec: 147 | serviceAccountName: haproxy-ingress-service-account 148 | containers: 149 | - name: haproxy-ingress 150 | image: haproxytech/kubernetes-ingress 151 | args: 152 | - --configmap=haproxy-controller/haproxy 153 | - --default-backend-service=haproxy-controller/ingress-default-backend 154 | securityContext: 155 | runAsUser: 1000 156 | runAsGroup: 1000 157 | capabilities: 158 | drop: 159 | - ALL 160 | add: 161 | - NET_BIND_SERVICE 162 | resources: 163 | requests: 164 | cpu: "500m" 165 | memory: "50Mi" 166 | livenessProbe: 167 | httpGet: 168 | path: /healthz 169 | port: 1042 170 | ports: 171 | - name: http 172 | containerPort: 80 173 | - name: https 174 | containerPort: 443 175 | - name: stat 176 | containerPort: 1024 177 | env: 178 | - name: TZ 179 | value: "Etc/UTC" 180 | - name: POD_NAME 181 | valueFrom: 182 | fieldRef: 183 | fieldPath: metadata.name 184 | - name: POD_NAMESPACE 185 | valueFrom: 186 | fieldRef: 187 | fieldPath: metadata.namespace 188 | initContainers: 189 | - name: sysctl 190 | image: busybox:musl 191 | command: 192 | - /bin/sh 193 | - -c 194 | - sysctl -w net.ipv4.ip_unprivileged_port_start=0 195 | securityContext: 196 | privileged: true 197 | --- 198 | apiVersion: v1 199 | kind: Service 200 | metadata: 201 | labels: 202 | run: haproxy-ingress 203 | name: haproxy-ingress 204 | namespace: haproxy-controller 205 | annotations: 206 | service.beta.kubernetes.io/aws-load-balancer-type: "nlb" 207 | dns.alpha.kubernetes.io/external: foo.jomo.click, bar.jomo.click 208 | spec: 209 | selector: 210 | run: haproxy-ingress 211 | type: LoadBalancer 212 | ports: 213 | - name: http 214 | port: 80 215 | protocol: TCP 216 | targetPort: 80 217 | - name: https 218 | port: 443 219 | protocol: TCP 220 | targetPort: 443 221 | - name: stat 222 | port: 1024 223 | protocol: TCP 224 | targetPort: 1024 225 | -------------------------------------------------------------------------------- /06_tools/06_cert_manager/01_kops/k8s/haproxy-ingress-controller.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: haproxy-controller 6 | 7 | --- 8 | apiVersion: v1 9 | kind: ServiceAccount 10 | metadata: 11 | name: haproxy-ingress-service-account 12 | namespace: haproxy-controller 13 | 14 | --- 15 | kind: ClusterRole 16 | apiVersion: rbac.authorization.k8s.io/v1 17 | metadata: 18 | name: haproxy-ingress-cluster-role 19 | rules: 20 | - apiGroups: 21 | - "" 22 | resources: 23 | - configmaps 24 | - endpoints 25 | - nodes 26 | - pods 27 | - services 28 | - namespaces 29 | - events 30 | - serviceaccounts 31 | verbs: 32 | - get 33 | - list 34 | - watch 35 | - apiGroups: 36 | - "extensions" 37 | - "networking.k8s.io" 38 | resources: 39 | - ingresses 40 | - ingresses/status 41 | - ingressclasses 42 | verbs: 43 | - get 44 | - list 45 | - watch 46 | - apiGroups: 47 | - "extensions" 48 | - "networking.k8s.io" 49 | resources: 50 | - ingresses/status 51 | verbs: 52 | - update 53 | - apiGroups: 54 | - "" 55 | resources: 56 | - secrets 57 | verbs: 58 | - get 59 | - list 60 | - watch 61 | - create 62 | - patch 63 | - update 64 | 65 | --- 66 | kind: ClusterRoleBinding 67 | apiVersion: rbac.authorization.k8s.io/v1 68 | metadata: 69 | name: haproxy-ingress-cluster-role-binding 70 | namespace: haproxy-controller 71 | roleRef: 72 | apiGroup: rbac.authorization.k8s.io 73 | kind: ClusterRole 74 | name: haproxy-ingress-cluster-role 75 | subjects: 76 | - kind: ServiceAccount 77 | name: haproxy-ingress-service-account 78 | namespace: haproxy-controller 79 | 80 | --- 81 | apiVersion: v1 82 | kind: ConfigMap 83 | metadata: 84 | name: haproxy 85 | namespace: haproxy-controller 86 | data: 87 | syslog-server: "address:stdout, format: raw, facility:daemon, level:debug" 88 | --- 89 | apiVersion: apps/v1 90 | kind: Deployment 91 | metadata: 92 | labels: 93 | run: ingress-default-backend 94 | name: ingress-default-backend 95 | namespace: haproxy-controller 96 | spec: 97 | replicas: 1 98 | selector: 99 | matchLabels: 100 | run: ingress-default-backend 101 | template: 102 | metadata: 103 | labels: 104 | run: ingress-default-backend 105 | spec: 106 | containers: 107 | - name: ingress-default-backend 108 | image: gcr.io/google_containers/defaultbackend:1.0 109 | ports: 110 | - containerPort: 8080 111 | 112 | --- 113 | apiVersion: v1 114 | kind: Service 115 | metadata: 116 | labels: 117 | run: ingress-default-backend 118 | name: ingress-default-backend 119 | namespace: haproxy-controller 120 | spec: 121 | selector: 122 | run: ingress-default-backend 123 | ports: 124 | - name: port-1 125 | port: 8080 126 | protocol: TCP 127 | targetPort: 8080 128 | 129 | --- 130 | apiVersion: apps/v1 131 | kind: Deployment 132 | metadata: 133 | labels: 134 | run: haproxy-ingress 135 | name: haproxy-ingress 136 | namespace: haproxy-controller 137 | spec: 138 | replicas: 1 139 | selector: 140 | matchLabels: 141 | run: haproxy-ingress 142 | template: 143 | metadata: 144 | labels: 145 | run: haproxy-ingress 146 | spec: 147 | serviceAccountName: haproxy-ingress-service-account 148 | containers: 149 | - name: haproxy-ingress 150 | image: haproxytech/kubernetes-ingress 151 | args: 152 | - --configmap=haproxy-controller/haproxy 153 | - --default-backend-service=haproxy-controller/ingress-default-backend 154 | securityContext: 155 | runAsUser: 1000 156 | runAsGroup: 1000 157 | capabilities: 158 | drop: 159 | - ALL 160 | add: 161 | - NET_BIND_SERVICE 162 | resources: 163 | requests: 164 | cpu: "500m" 165 | memory: "50Mi" 166 | livenessProbe: 167 | httpGet: 168 | path: /healthz 169 | port: 1042 170 | ports: 171 | - name: http 172 | containerPort: 80 173 | - name: https 174 | containerPort: 443 175 | - name: stat 176 | containerPort: 1024 177 | env: 178 | - name: TZ 179 | value: "Etc/UTC" 180 | - name: POD_NAME 181 | valueFrom: 182 | fieldRef: 183 | fieldPath: metadata.name 184 | - name: POD_NAMESPACE 185 | valueFrom: 186 | fieldRef: 187 | fieldPath: metadata.namespace 188 | initContainers: 189 | - name: sysctl 190 | image: busybox:musl 191 | command: 192 | - /bin/sh 193 | - -c 194 | - sysctl -w net.ipv4.ip_unprivileged_port_start=0 195 | securityContext: 196 | privileged: true 197 | --- 198 | apiVersion: v1 199 | kind: Service 200 | metadata: 201 | labels: 202 | run: haproxy-ingress 203 | name: haproxy-ingress 204 | namespace: haproxy-controller 205 | annotations: 206 | service.beta.kubernetes.io/aws-load-balancer-type: "nlb" 207 | dns.alpha.kubernetes.io/external: foo.jomo.click, bar.jomo.click 208 | spec: 209 | selector: 210 | run: haproxy-ingress 211 | type: LoadBalancer 212 | ports: 213 | - name: http 214 | port: 80 215 | protocol: TCP 216 | targetPort: 80 217 | - name: https 218 | port: 443 219 | protocol: TCP 220 | targetPort: 443 221 | - name: stat 222 | port: 1024 223 | protocol: TCP 224 | targetPort: 1024 225 | -------------------------------------------------------------------------------- /003_01_probes/node-app/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "app", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "prettier": "^2.1.2", 13 | "ts-node": "^9.0.0", 14 | "typescript": "^4.0.5" 15 | }, 16 | "devDependencies": { 17 | "@types/node": "^14.14.8" 18 | } 19 | }, 20 | "node_modules/@types/node": { 21 | "version": "14.14.10", 22 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.10.tgz", 23 | "integrity": "sha512-J32dgx2hw8vXrSbu4ZlVhn1Nm3GbeCFNw2FWL8S5QKucHGY0cyNwjdQdO+KMBZ4wpmC7KhLCiNsdk1RFRIYUQQ==", 24 | "dev": true 25 | }, 26 | "node_modules/arg": { 27 | "version": "4.1.3", 28 | "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", 29 | "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" 30 | }, 31 | "node_modules/buffer-from": { 32 | "version": "1.1.1", 33 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 34 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" 35 | }, 36 | "node_modules/diff": { 37 | "version": "4.0.2", 38 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", 39 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", 40 | "engines": { 41 | "node": ">=0.3.1" 42 | } 43 | }, 44 | "node_modules/make-error": { 45 | "version": "1.3.6", 46 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", 47 | "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" 48 | }, 49 | "node_modules/prettier": { 50 | "version": "2.2.1", 51 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", 52 | "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", 53 | "bin": { 54 | "prettier": "bin-prettier.js" 55 | }, 56 | "engines": { 57 | "node": ">=10.13.0" 58 | } 59 | }, 60 | "node_modules/source-map": { 61 | "version": "0.6.1", 62 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 63 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 64 | "engines": { 65 | "node": ">=0.10.0" 66 | } 67 | }, 68 | "node_modules/source-map-support": { 69 | "version": "0.5.19", 70 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", 71 | "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", 72 | "dependencies": { 73 | "buffer-from": "^1.0.0", 74 | "source-map": "^0.6.0" 75 | } 76 | }, 77 | "node_modules/ts-node": { 78 | "version": "9.0.0", 79 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.0.0.tgz", 80 | "integrity": "sha512-/TqB4SnererCDR/vb4S/QvSZvzQMJN8daAslg7MeaiHvD8rDZsSfXmNeNumyZZzMned72Xoq/isQljYSt8Ynfg==", 81 | "dependencies": { 82 | "arg": "^4.1.0", 83 | "diff": "^4.0.1", 84 | "make-error": "^1.1.1", 85 | "source-map-support": "^0.5.17", 86 | "yn": "3.1.1" 87 | }, 88 | "bin": { 89 | "ts-node": "dist/bin.js", 90 | "ts-node-script": "dist/bin-script.js", 91 | "ts-node-transpile-only": "dist/bin-transpile.js", 92 | "ts-script": "dist/bin-script-deprecated.js" 93 | }, 94 | "engines": { 95 | "node": ">=10.0.0" 96 | } 97 | }, 98 | "node_modules/typescript": { 99 | "version": "4.1.2", 100 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.2.tgz", 101 | "integrity": "sha512-thGloWsGH3SOxv1SoY7QojKi0tc+8FnOmiarEGMbd/lar7QOEd3hvlx3Fp5y6FlDUGl9L+pd4n2e+oToGMmhRQ==", 102 | "bin": { 103 | "tsc": "bin/tsc", 104 | "tsserver": "bin/tsserver" 105 | }, 106 | "engines": { 107 | "node": ">=4.2.0" 108 | } 109 | }, 110 | "node_modules/yn": { 111 | "version": "3.1.1", 112 | "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", 113 | "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", 114 | "engines": { 115 | "node": ">=6" 116 | } 117 | } 118 | }, 119 | "dependencies": { 120 | "@types/node": { 121 | "version": "14.14.10", 122 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.10.tgz", 123 | "integrity": "sha512-J32dgx2hw8vXrSbu4ZlVhn1Nm3GbeCFNw2FWL8S5QKucHGY0cyNwjdQdO+KMBZ4wpmC7KhLCiNsdk1RFRIYUQQ==", 124 | "dev": true 125 | }, 126 | "arg": { 127 | "version": "4.1.3", 128 | "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", 129 | "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" 130 | }, 131 | "buffer-from": { 132 | "version": "1.1.1", 133 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 134 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" 135 | }, 136 | "diff": { 137 | "version": "4.0.2", 138 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", 139 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" 140 | }, 141 | "make-error": { 142 | "version": "1.3.6", 143 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", 144 | "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" 145 | }, 146 | "prettier": { 147 | "version": "2.2.1", 148 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", 149 | "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==" 150 | }, 151 | "source-map": { 152 | "version": "0.6.1", 153 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 154 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" 155 | }, 156 | "source-map-support": { 157 | "version": "0.5.19", 158 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", 159 | "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", 160 | "requires": { 161 | "buffer-from": "^1.0.0", 162 | "source-map": "^0.6.0" 163 | } 164 | }, 165 | "ts-node": { 166 | "version": "9.0.0", 167 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.0.0.tgz", 168 | "integrity": "sha512-/TqB4SnererCDR/vb4S/QvSZvzQMJN8daAslg7MeaiHvD8rDZsSfXmNeNumyZZzMned72Xoq/isQljYSt8Ynfg==", 169 | "requires": { 170 | "arg": "^4.1.0", 171 | "diff": "^4.0.1", 172 | "make-error": "^1.1.1", 173 | "source-map-support": "^0.5.17", 174 | "yn": "3.1.1" 175 | } 176 | }, 177 | "typescript": { 178 | "version": "4.1.2", 179 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.2.tgz", 180 | "integrity": "sha512-thGloWsGH3SOxv1SoY7QojKi0tc+8FnOmiarEGMbd/lar7QOEd3hvlx3Fp5y6FlDUGl9L+pd4n2e+oToGMmhRQ==" 181 | }, 182 | "yn": { 183 | "version": "3.1.1", 184 | "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", 185 | "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" 186 | } 187 | } 188 | } 189 | -------------------------------------------------------------------------------- /04_services/004_01_services/node-app/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "app", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "prettier": "^2.1.2", 13 | "ts-node": "^9.0.0", 14 | "typescript": "^4.0.5" 15 | }, 16 | "devDependencies": { 17 | "@types/node": "^14.14.8" 18 | } 19 | }, 20 | "node_modules/@types/node": { 21 | "version": "14.14.8", 22 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.8.tgz", 23 | "integrity": "sha512-z/5Yd59dCKI5kbxauAJgw6dLPzW+TNOItNE00PkpzNwUIEwdj/Lsqwq94H5DdYBX7C13aRA0CY32BK76+neEUA==", 24 | "dev": true 25 | }, 26 | "node_modules/arg": { 27 | "version": "4.1.3", 28 | "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", 29 | "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" 30 | }, 31 | "node_modules/buffer-from": { 32 | "version": "1.1.1", 33 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 34 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" 35 | }, 36 | "node_modules/diff": { 37 | "version": "4.0.2", 38 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", 39 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", 40 | "engines": { 41 | "node": ">=0.3.1" 42 | } 43 | }, 44 | "node_modules/make-error": { 45 | "version": "1.3.6", 46 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", 47 | "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" 48 | }, 49 | "node_modules/prettier": { 50 | "version": "2.1.2", 51 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.2.tgz", 52 | "integrity": "sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==", 53 | "bin": { 54 | "prettier": "bin-prettier.js" 55 | }, 56 | "engines": { 57 | "node": ">=10.13.0" 58 | } 59 | }, 60 | "node_modules/source-map": { 61 | "version": "0.6.1", 62 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 63 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 64 | "engines": { 65 | "node": ">=0.10.0" 66 | } 67 | }, 68 | "node_modules/source-map-support": { 69 | "version": "0.5.19", 70 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", 71 | "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", 72 | "dependencies": { 73 | "buffer-from": "^1.0.0", 74 | "source-map": "^0.6.0" 75 | } 76 | }, 77 | "node_modules/ts-node": { 78 | "version": "9.0.0", 79 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.0.0.tgz", 80 | "integrity": "sha512-/TqB4SnererCDR/vb4S/QvSZvzQMJN8daAslg7MeaiHvD8rDZsSfXmNeNumyZZzMned72Xoq/isQljYSt8Ynfg==", 81 | "dependencies": { 82 | "arg": "^4.1.0", 83 | "diff": "^4.0.1", 84 | "make-error": "^1.1.1", 85 | "source-map-support": "^0.5.17", 86 | "yn": "3.1.1" 87 | }, 88 | "bin": { 89 | "ts-node": "dist/bin.js", 90 | "ts-node-script": "dist/bin-script.js", 91 | "ts-node-transpile-only": "dist/bin-transpile.js", 92 | "ts-script": "dist/bin-script-deprecated.js" 93 | }, 94 | "engines": { 95 | "node": ">=10.0.0" 96 | } 97 | }, 98 | "node_modules/typescript": { 99 | "version": "4.0.5", 100 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.5.tgz", 101 | "integrity": "sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ==", 102 | "bin": { 103 | "tsc": "bin/tsc", 104 | "tsserver": "bin/tsserver" 105 | }, 106 | "engines": { 107 | "node": ">=4.2.0" 108 | } 109 | }, 110 | "node_modules/yn": { 111 | "version": "3.1.1", 112 | "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", 113 | "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", 114 | "engines": { 115 | "node": ">=6" 116 | } 117 | } 118 | }, 119 | "dependencies": { 120 | "@types/node": { 121 | "version": "14.14.8", 122 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.8.tgz", 123 | "integrity": "sha512-z/5Yd59dCKI5kbxauAJgw6dLPzW+TNOItNE00PkpzNwUIEwdj/Lsqwq94H5DdYBX7C13aRA0CY32BK76+neEUA==", 124 | "dev": true 125 | }, 126 | "arg": { 127 | "version": "4.1.3", 128 | "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", 129 | "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" 130 | }, 131 | "buffer-from": { 132 | "version": "1.1.1", 133 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 134 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" 135 | }, 136 | "diff": { 137 | "version": "4.0.2", 138 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", 139 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" 140 | }, 141 | "make-error": { 142 | "version": "1.3.6", 143 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", 144 | "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" 145 | }, 146 | "prettier": { 147 | "version": "2.1.2", 148 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.2.tgz", 149 | "integrity": "sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==" 150 | }, 151 | "source-map": { 152 | "version": "0.6.1", 153 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 154 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" 155 | }, 156 | "source-map-support": { 157 | "version": "0.5.19", 158 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", 159 | "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", 160 | "requires": { 161 | "buffer-from": "^1.0.0", 162 | "source-map": "^0.6.0" 163 | } 164 | }, 165 | "ts-node": { 166 | "version": "9.0.0", 167 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.0.0.tgz", 168 | "integrity": "sha512-/TqB4SnererCDR/vb4S/QvSZvzQMJN8daAslg7MeaiHvD8rDZsSfXmNeNumyZZzMned72Xoq/isQljYSt8Ynfg==", 169 | "requires": { 170 | "arg": "^4.1.0", 171 | "diff": "^4.0.1", 172 | "make-error": "^1.1.1", 173 | "source-map-support": "^0.5.17", 174 | "yn": "3.1.1" 175 | } 176 | }, 177 | "typescript": { 178 | "version": "4.0.5", 179 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.5.tgz", 180 | "integrity": "sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ==" 181 | }, 182 | "yn": { 183 | "version": "3.1.1", 184 | "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", 185 | "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" 186 | } 187 | } 188 | } 189 | -------------------------------------------------------------------------------- /06_tools/007_alb_ingress/01_eks/iam_policy.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Effect": "Allow", 6 | "Action": [ 7 | "iam:CreateServiceLinkedRole", 8 | "ec2:DescribeAccountAttributes", 9 | "ec2:DescribeAddresses", 10 | "ec2:DescribeAvailabilityZones", 11 | "ec2:DescribeInternetGateways", 12 | "ec2:DescribeVpcs", 13 | "ec2:DescribeSubnets", 14 | "ec2:DescribeSecurityGroups", 15 | "ec2:DescribeInstances", 16 | "ec2:DescribeNetworkInterfaces", 17 | "ec2:DescribeTags", 18 | "ec2:GetCoipPoolUsage", 19 | "ec2:DescribeCoipPools", 20 | "elasticloadbalancing:DescribeLoadBalancers", 21 | "elasticloadbalancing:DescribeLoadBalancerAttributes", 22 | "elasticloadbalancing:DescribeListeners", 23 | "elasticloadbalancing:DescribeListenerCertificates", 24 | "elasticloadbalancing:DescribeSSLPolicies", 25 | "elasticloadbalancing:DescribeRules", 26 | "elasticloadbalancing:DescribeTargetGroups", 27 | "elasticloadbalancing:DescribeTargetGroupAttributes", 28 | "elasticloadbalancing:DescribeTargetHealth", 29 | "elasticloadbalancing:DescribeTags" 30 | ], 31 | "Resource": "*" 32 | }, 33 | { 34 | "Effect": "Allow", 35 | "Action": [ 36 | "cognito-idp:DescribeUserPoolClient", 37 | "acm:ListCertificates", 38 | "acm:DescribeCertificate", 39 | "iam:ListServerCertificates", 40 | "iam:GetServerCertificate", 41 | "waf-regional:GetWebACL", 42 | "waf-regional:GetWebACLForResource", 43 | "waf-regional:AssociateWebACL", 44 | "waf-regional:DisassociateWebACL", 45 | "wafv2:GetWebACL", 46 | "wafv2:GetWebACLForResource", 47 | "wafv2:AssociateWebACL", 48 | "wafv2:DisassociateWebACL", 49 | "shield:GetSubscriptionState", 50 | "shield:DescribeProtection", 51 | "shield:CreateProtection", 52 | "shield:DeleteProtection" 53 | ], 54 | "Resource": "*" 55 | }, 56 | { 57 | "Effect": "Allow", 58 | "Action": [ 59 | "ec2:AuthorizeSecurityGroupIngress", 60 | "ec2:RevokeSecurityGroupIngress" 61 | ], 62 | "Resource": "*" 63 | }, 64 | { 65 | "Effect": "Allow", 66 | "Action": [ 67 | "ec2:CreateSecurityGroup" 68 | ], 69 | "Resource": "*" 70 | }, 71 | { 72 | "Effect": "Allow", 73 | "Action": [ 74 | "ec2:CreateTags" 75 | ], 76 | "Resource": "arn:aws:ec2:*:*:security-group/*", 77 | "Condition": { 78 | "StringEquals": { 79 | "ec2:CreateAction": "CreateSecurityGroup" 80 | }, 81 | "Null": { 82 | "aws:RequestTag/elbv2.k8s.aws/cluster": "false" 83 | } 84 | } 85 | }, 86 | { 87 | "Effect": "Allow", 88 | "Action": [ 89 | "ec2:CreateTags", 90 | "ec2:DeleteTags" 91 | ], 92 | "Resource": "arn:aws:ec2:*:*:security-group/*", 93 | "Condition": { 94 | "Null": { 95 | "aws:RequestTag/elbv2.k8s.aws/cluster": "true", 96 | "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" 97 | } 98 | } 99 | }, 100 | { 101 | "Effect": "Allow", 102 | "Action": [ 103 | "ec2:AuthorizeSecurityGroupIngress", 104 | "ec2:RevokeSecurityGroupIngress", 105 | "ec2:DeleteSecurityGroup" 106 | ], 107 | "Resource": "*", 108 | "Condition": { 109 | "Null": { 110 | "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" 111 | } 112 | } 113 | }, 114 | { 115 | "Effect": "Allow", 116 | "Action": [ 117 | "elasticloadbalancing:CreateLoadBalancer", 118 | "elasticloadbalancing:CreateTargetGroup" 119 | ], 120 | "Resource": "*", 121 | "Condition": { 122 | "Null": { 123 | "aws:RequestTag/elbv2.k8s.aws/cluster": "false" 124 | } 125 | } 126 | }, 127 | { 128 | "Effect": "Allow", 129 | "Action": [ 130 | "elasticloadbalancing:CreateListener", 131 | "elasticloadbalancing:DeleteListener", 132 | "elasticloadbalancing:CreateRule", 133 | "elasticloadbalancing:DeleteRule" 134 | ], 135 | "Resource": "*" 136 | }, 137 | { 138 | "Effect": "Allow", 139 | "Action": [ 140 | "elasticloadbalancing:AddTags", 141 | "elasticloadbalancing:RemoveTags" 142 | ], 143 | "Resource": [ 144 | "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*", 145 | "arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*", 146 | "arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*" 147 | ], 148 | "Condition": { 149 | "Null": { 150 | "aws:RequestTag/elbv2.k8s.aws/cluster": "true", 151 | "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" 152 | } 153 | } 154 | }, 155 | { 156 | "Effect": "Allow", 157 | "Action": [ 158 | "elasticloadbalancing:AddTags", 159 | "elasticloadbalancing:RemoveTags" 160 | ], 161 | "Resource": [ 162 | "arn:aws:elasticloadbalancing:*:*:listener/net/*/*/*", 163 | "arn:aws:elasticloadbalancing:*:*:listener/app/*/*/*", 164 | "arn:aws:elasticloadbalancing:*:*:listener-rule/net/*/*/*", 165 | "arn:aws:elasticloadbalancing:*:*:listener-rule/app/*/*/*" 166 | ] 167 | }, 168 | { 169 | "Effect": "Allow", 170 | "Action": [ 171 | "elasticloadbalancing:ModifyLoadBalancerAttributes", 172 | "elasticloadbalancing:SetIpAddressType", 173 | "elasticloadbalancing:SetSecurityGroups", 174 | "elasticloadbalancing:SetSubnets", 175 | "elasticloadbalancing:DeleteLoadBalancer", 176 | "elasticloadbalancing:ModifyTargetGroup", 177 | "elasticloadbalancing:ModifyTargetGroupAttributes", 178 | "elasticloadbalancing:DeleteTargetGroup" 179 | ], 180 | "Resource": "*", 181 | "Condition": { 182 | "Null": { 183 | "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" 184 | } 185 | } 186 | }, 187 | { 188 | "Effect": "Allow", 189 | "Action": [ 190 | "elasticloadbalancing:RegisterTargets", 191 | "elasticloadbalancing:DeregisterTargets" 192 | ], 193 | "Resource": "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*" 194 | }, 195 | { 196 | "Effect": "Allow", 197 | "Action": [ 198 | "elasticloadbalancing:SetWebAcl", 199 | "elasticloadbalancing:ModifyListener", 200 | "elasticloadbalancing:AddListenerCertificates", 201 | "elasticloadbalancing:RemoveListenerCertificates", 202 | "elasticloadbalancing:ModifyRule" 203 | ], 204 | "Resource": "*" 205 | } 206 | ] 207 | } 208 | -------------------------------------------------------------------------------- /06_tools/007_alb_ingress/01_eks/v2_2_0_full.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apiextensions.k8s.io/v1 2 | kind: CustomResourceDefinition 3 | metadata: 4 | annotations: 5 | controller-gen.kubebuilder.io/version: v0.5.0 6 | creationTimestamp: null 7 | labels: 8 | app.kubernetes.io/name: aws-load-balancer-controller 9 | name: ingressclassparams.elbv2.k8s.aws 10 | spec: 11 | group: elbv2.k8s.aws 12 | names: 13 | kind: IngressClassParams 14 | listKind: IngressClassParamsList 15 | plural: ingressclassparams 16 | singular: ingressclassparams 17 | scope: Cluster 18 | versions: 19 | - additionalPrinterColumns: 20 | - description: The Ingress Group name 21 | jsonPath: .spec.group.name 22 | name: GROUP-NAME 23 | type: string 24 | - description: The AWS Load Balancer scheme 25 | jsonPath: .spec.scheme 26 | name: SCHEME 27 | type: string 28 | - description: The AWS Load Balancer ipAddressType 29 | jsonPath: .spec.ipAddressType 30 | name: IP-ADDRESS-TYPE 31 | type: string 32 | - jsonPath: .metadata.creationTimestamp 33 | name: AGE 34 | type: date 35 | name: v1beta1 36 | schema: 37 | openAPIV3Schema: 38 | description: IngressClassParams is the Schema for the IngressClassParams API 39 | properties: 40 | apiVersion: 41 | description: 'APIVersion defines the versioned schema of this representation 42 | of an object. Servers should convert recognized schemas to the latest 43 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 44 | type: string 45 | kind: 46 | description: 'Kind is a string value representing the REST resource this 47 | object represents. Servers may infer this from the endpoint the client 48 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 49 | type: string 50 | metadata: 51 | type: object 52 | spec: 53 | description: IngressClassParamsSpec defines the desired state of IngressClassParams 54 | properties: 55 | group: 56 | description: Group defines the IngressGroup for all Ingresses that 57 | belong to IngressClass with this IngressClassParams. 58 | properties: 59 | name: 60 | description: Name is the name of IngressGroup. 61 | type: string 62 | required: 63 | - name 64 | type: object 65 | ipAddressType: 66 | description: IPAddressType defines the ip address type for all Ingresses 67 | that belong to IngressClass with this IngressClassParams. 68 | enum: 69 | - ipv4 70 | - dualstack 71 | type: string 72 | namespaceSelector: 73 | description: NamespaceSelector restrict the namespaces of Ingresses 74 | that are allowed to specify the IngressClass with this IngressClassParams. 75 | * if absent or present but empty, it selects all namespaces. 76 | properties: 77 | matchExpressions: 78 | description: matchExpressions is a list of label selector requirements. 79 | The requirements are ANDed. 80 | items: 81 | description: A label selector requirement is a selector that 82 | contains values, a key, and an operator that relates the key 83 | and values. 84 | properties: 85 | key: 86 | description: key is the label key that the selector applies 87 | to. 88 | type: string 89 | operator: 90 | description: operator represents a key's relationship to 91 | a set of values. Valid operators are In, NotIn, Exists 92 | and DoesNotExist. 93 | type: string 94 | values: 95 | description: values is an array of string values. If the 96 | operator is In or NotIn, the values array must be non-empty. 97 | If the operator is Exists or DoesNotExist, the values 98 | array must be empty. This array is replaced during a strategic 99 | merge patch. 100 | items: 101 | type: string 102 | type: array 103 | required: 104 | - key 105 | - operator 106 | type: object 107 | type: array 108 | matchLabels: 109 | additionalProperties: 110 | type: string 111 | description: matchLabels is a map of {key,value} pairs. A single 112 | {key,value} in the matchLabels map is equivalent to an element 113 | of matchExpressions, whose key field is "key", the operator 114 | is "In", and the values array contains only "value". The requirements 115 | are ANDed. 116 | type: object 117 | type: object 118 | scheme: 119 | description: Scheme defines the scheme for all Ingresses that belong 120 | to IngressClass with this IngressClassParams. 121 | enum: 122 | - internal 123 | - internet-facing 124 | type: string 125 | tags: 126 | description: Tags defines list of Tags on AWS resources provisioned 127 | for Ingresses that belong to IngressClass with this IngressClassParams. 128 | items: 129 | description: Tag defines a AWS Tag on resources. 130 | properties: 131 | key: 132 | description: The key of the tag. 133 | type: string 134 | value: 135 | description: The value of the tag. 136 | type: string 137 | required: 138 | - key 139 | - value 140 | type: object 141 | type: array 142 | type: object 143 | type: object 144 | served: true 145 | storage: true 146 | subresources: {} 147 | status: 148 | acceptedNames: 149 | kind: "" 150 | plural: "" 151 | conditions: [] 152 | storedVersions: [] 153 | --- 154 | apiVersion: apiextensions.k8s.io/v1 155 | kind: CustomResourceDefinition 156 | metadata: 157 | annotations: 158 | controller-gen.kubebuilder.io/version: v0.5.0 159 | creationTimestamp: null 160 | labels: 161 | app.kubernetes.io/name: aws-load-balancer-controller 162 | name: targetgroupbindings.elbv2.k8s.aws 163 | spec: 164 | group: elbv2.k8s.aws 165 | names: 166 | kind: TargetGroupBinding 167 | listKind: TargetGroupBindingList 168 | plural: targetgroupbindings 169 | singular: targetgroupbinding 170 | scope: Namespaced 171 | versions: 172 | - additionalPrinterColumns: 173 | - description: The Kubernetes Service's name 174 | jsonPath: .spec.serviceRef.name 175 | name: SERVICE-NAME 176 | type: string 177 | - description: The Kubernetes Service's port 178 | jsonPath: .spec.serviceRef.port 179 | name: SERVICE-PORT 180 | type: string 181 | - description: The AWS TargetGroup's TargetType 182 | jsonPath: .spec.targetType 183 | name: TARGET-TYPE 184 | type: string 185 | - description: The AWS TargetGroup's Amazon Resource Name 186 | jsonPath: .spec.targetGroupARN 187 | name: ARN 188 | priority: 1 189 | type: string 190 | - jsonPath: .metadata.creationTimestamp 191 | name: AGE 192 | type: date 193 | name: v1alpha1 194 | schema: 195 | openAPIV3Schema: 196 | description: TargetGroupBinding is the Schema for the TargetGroupBinding API 197 | properties: 198 | apiVersion: 199 | description: 'APIVersion defines the versioned schema of this representation 200 | of an object. Servers should convert recognized schemas to the latest 201 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 202 | type: string 203 | kind: 204 | description: 'Kind is a string value representing the REST resource this 205 | object represents. Servers may infer this from the endpoint the client 206 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 207 | type: string 208 | metadata: 209 | type: object 210 | spec: 211 | description: TargetGroupBindingSpec defines the desired state of TargetGroupBinding 212 | properties: 213 | networking: 214 | description: networking provides the networking setup for ELBV2 LoadBalancer 215 | to access targets in TargetGroup. 216 | properties: 217 | ingress: 218 | description: List of ingress rules to allow ELBV2 LoadBalancer 219 | to access targets in TargetGroup. 220 | items: 221 | properties: 222 | from: 223 | description: List of peers which should be able to access 224 | the targets in TargetGroup. At least one NetworkingPeer 225 | should be specified. 226 | items: 227 | description: NetworkingPeer defines the source/destination 228 | peer for networking rules. 229 | properties: 230 | ipBlock: 231 | description: IPBlock defines an IPBlock peer. If specified, 232 | none of the other fields can be set. 233 | properties: 234 | cidr: 235 | description: CIDR is the network CIDR. Both IPV4 236 | or IPV6 CIDR are accepted. 237 | type: string 238 | required: 239 | - cidr 240 | type: object 241 | securityGroup: 242 | description: SecurityGroup defines a SecurityGroup 243 | peer. If specified, none of the other fields can 244 | be set. 245 | properties: 246 | groupID: 247 | description: GroupID is the EC2 SecurityGroupID. 248 | type: string 249 | required: 250 | - groupID 251 | type: object 252 | type: object 253 | type: array 254 | ports: 255 | description: List of ports which should be made accessible 256 | on the targets in TargetGroup. If ports is empty or unspecified, 257 | it defaults to all ports with TCP. 258 | items: 259 | properties: 260 | port: 261 | anyOf: 262 | - type: integer 263 | - type: string 264 | description: The port which traffic must match. When 265 | NodePort endpoints(instance TargetType) is used, 266 | this must be a numerical port. When Port endpoints(ip 267 | TargetType) is used, this can be either numerical 268 | or named port on pods. if port is unspecified, it 269 | defaults to all ports. 270 | x-kubernetes-int-or-string: true 271 | protocol: 272 | description: The protocol which traffic must match. 273 | If protocol is unspecified, it defaults to TCP. 274 | enum: 275 | - TCP 276 | - UDP 277 | type: string 278 | type: object 279 | type: array 280 | required: 281 | - from 282 | - ports 283 | type: object 284 | type: array 285 | type: object 286 | serviceRef: 287 | description: serviceRef is a reference to a Kubernetes Service and 288 | ServicePort. 289 | properties: 290 | name: 291 | description: Name is the name of the Service. 292 | type: string 293 | port: 294 | anyOf: 295 | - type: integer 296 | - type: string 297 | description: Port is the port of the ServicePort. 298 | x-kubernetes-int-or-string: true 299 | required: 300 | - name 301 | - port 302 | type: object 303 | targetGroupARN: 304 | description: targetGroupARN is the Amazon Resource Name (ARN) for 305 | the TargetGroup. 306 | type: string 307 | targetType: 308 | description: targetType is the TargetType of TargetGroup. If unspecified, 309 | it will be automatically inferred. 310 | enum: 311 | - instance 312 | - ip 313 | type: string 314 | required: 315 | - serviceRef 316 | - targetGroupARN 317 | type: object 318 | status: 319 | description: TargetGroupBindingStatus defines the observed state of TargetGroupBinding 320 | properties: 321 | observedGeneration: 322 | description: The generation observed by the TargetGroupBinding controller. 323 | format: int64 324 | type: integer 325 | type: object 326 | type: object 327 | served: true 328 | storage: false 329 | subresources: 330 | status: {} 331 | - additionalPrinterColumns: 332 | - description: The Kubernetes Service's name 333 | jsonPath: .spec.serviceRef.name 334 | name: SERVICE-NAME 335 | type: string 336 | - description: The Kubernetes Service's port 337 | jsonPath: .spec.serviceRef.port 338 | name: SERVICE-PORT 339 | type: string 340 | - description: The AWS TargetGroup's TargetType 341 | jsonPath: .spec.targetType 342 | name: TARGET-TYPE 343 | type: string 344 | - description: The AWS TargetGroup's Amazon Resource Name 345 | jsonPath: .spec.targetGroupARN 346 | name: ARN 347 | priority: 1 348 | type: string 349 | - jsonPath: .metadata.creationTimestamp 350 | name: AGE 351 | type: date 352 | name: v1beta1 353 | schema: 354 | openAPIV3Schema: 355 | description: TargetGroupBinding is the Schema for the TargetGroupBinding API 356 | properties: 357 | apiVersion: 358 | description: 'APIVersion defines the versioned schema of this representation 359 | of an object. Servers should convert recognized schemas to the latest 360 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 361 | type: string 362 | kind: 363 | description: 'Kind is a string value representing the REST resource this 364 | object represents. Servers may infer this from the endpoint the client 365 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 366 | type: string 367 | metadata: 368 | type: object 369 | spec: 370 | description: TargetGroupBindingSpec defines the desired state of TargetGroupBinding 371 | properties: 372 | networking: 373 | description: networking defines the networking rules to allow ELBV2 374 | LoadBalancer to access targets in TargetGroup. 375 | properties: 376 | ingress: 377 | description: List of ingress rules to allow ELBV2 LoadBalancer 378 | to access targets in TargetGroup. 379 | items: 380 | description: NetworkingIngressRule defines a particular set 381 | of traffic that is allowed to access TargetGroup's targets. 382 | properties: 383 | from: 384 | description: List of peers which should be able to access 385 | the targets in TargetGroup. At least one NetworkingPeer 386 | should be specified. 387 | items: 388 | description: NetworkingPeer defines the source/destination 389 | peer for networking rules. 390 | properties: 391 | ipBlock: 392 | description: IPBlock defines an IPBlock peer. If specified, 393 | none of the other fields can be set. 394 | properties: 395 | cidr: 396 | description: CIDR is the network CIDR. Both IPV4 397 | or IPV6 CIDR are accepted. 398 | type: string 399 | required: 400 | - cidr 401 | type: object 402 | securityGroup: 403 | description: SecurityGroup defines a SecurityGroup 404 | peer. If specified, none of the other fields can 405 | be set. 406 | properties: 407 | groupID: 408 | description: GroupID is the EC2 SecurityGroupID. 409 | type: string 410 | required: 411 | - groupID 412 | type: object 413 | type: object 414 | type: array 415 | ports: 416 | description: List of ports which should be made accessible 417 | on the targets in TargetGroup. If ports is empty or unspecified, 418 | it defaults to all ports with TCP. 419 | items: 420 | description: NetworkingPort defines the port and protocol 421 | for networking rules. 422 | properties: 423 | port: 424 | anyOf: 425 | - type: integer 426 | - type: string 427 | description: The port which traffic must match. When 428 | NodePort endpoints(instance TargetType) is used, 429 | this must be a numerical port. When Port endpoints(ip 430 | TargetType) is used, this can be either numerical 431 | or named port on pods. if port is unspecified, it 432 | defaults to all ports. 433 | x-kubernetes-int-or-string: true 434 | protocol: 435 | description: The protocol which traffic must match. 436 | If protocol is unspecified, it defaults to TCP. 437 | enum: 438 | - TCP 439 | - UDP 440 | type: string 441 | type: object 442 | type: array 443 | required: 444 | - from 445 | - ports 446 | type: object 447 | type: array 448 | type: object 449 | nodeSelector: 450 | description: node selector for instance type target groups to only 451 | register certain nodes 452 | properties: 453 | matchExpressions: 454 | description: matchExpressions is a list of label selector requirements. 455 | The requirements are ANDed. 456 | items: 457 | description: A label selector requirement is a selector that 458 | contains values, a key, and an operator that relates the key 459 | and values. 460 | properties: 461 | key: 462 | description: key is the label key that the selector applies 463 | to. 464 | type: string 465 | operator: 466 | description: operator represents a key's relationship to 467 | a set of values. Valid operators are In, NotIn, Exists 468 | and DoesNotExist. 469 | type: string 470 | values: 471 | description: values is an array of string values. If the 472 | operator is In or NotIn, the values array must be non-empty. 473 | If the operator is Exists or DoesNotExist, the values 474 | array must be empty. This array is replaced during a strategic 475 | merge patch. 476 | items: 477 | type: string 478 | type: array 479 | required: 480 | - key 481 | - operator 482 | type: object 483 | type: array 484 | matchLabels: 485 | additionalProperties: 486 | type: string 487 | description: matchLabels is a map of {key,value} pairs. A single 488 | {key,value} in the matchLabels map is equivalent to an element 489 | of matchExpressions, whose key field is "key", the operator 490 | is "In", and the values array contains only "value". The requirements 491 | are ANDed. 492 | type: object 493 | type: object 494 | serviceRef: 495 | description: serviceRef is a reference to a Kubernetes Service and 496 | ServicePort. 497 | properties: 498 | name: 499 | description: Name is the name of the Service. 500 | type: string 501 | port: 502 | anyOf: 503 | - type: integer 504 | - type: string 505 | description: Port is the port of the ServicePort. 506 | x-kubernetes-int-or-string: true 507 | required: 508 | - name 509 | - port 510 | type: object 511 | targetGroupARN: 512 | description: targetGroupARN is the Amazon Resource Name (ARN) for 513 | the TargetGroup. 514 | type: string 515 | targetType: 516 | description: targetType is the TargetType of TargetGroup. If unspecified, 517 | it will be automatically inferred. 518 | enum: 519 | - instance 520 | - ip 521 | type: string 522 | required: 523 | - serviceRef 524 | - targetGroupARN 525 | type: object 526 | status: 527 | description: TargetGroupBindingStatus defines the observed state of TargetGroupBinding 528 | properties: 529 | observedGeneration: 530 | description: The generation observed by the TargetGroupBinding controller. 531 | format: int64 532 | type: integer 533 | type: object 534 | type: object 535 | served: true 536 | storage: true 537 | subresources: 538 | status: {} 539 | status: 540 | acceptedNames: 541 | kind: "" 542 | plural: "" 543 | conditions: [] 544 | storedVersions: [] 545 | --- 546 | apiVersion: rbac.authorization.k8s.io/v1 547 | kind: Role 548 | metadata: 549 | labels: 550 | app.kubernetes.io/name: aws-load-balancer-controller 551 | name: aws-load-balancer-controller-leader-election-role 552 | namespace: kube-system 553 | rules: 554 | - apiGroups: 555 | - "" 556 | resources: 557 | - configmaps 558 | verbs: 559 | - create 560 | - apiGroups: 561 | - "" 562 | resourceNames: 563 | - aws-load-balancer-controller-leader 564 | resources: 565 | - configmaps 566 | verbs: 567 | - get 568 | - update 569 | - patch 570 | --- 571 | apiVersion: rbac.authorization.k8s.io/v1 572 | kind: ClusterRole 573 | metadata: 574 | creationTimestamp: null 575 | labels: 576 | app.kubernetes.io/name: aws-load-balancer-controller 577 | name: aws-load-balancer-controller-role 578 | rules: 579 | - apiGroups: 580 | - "" 581 | resources: 582 | - endpoints 583 | verbs: 584 | - get 585 | - list 586 | - watch 587 | - apiGroups: 588 | - "" 589 | resources: 590 | - events 591 | verbs: 592 | - create 593 | - patch 594 | - apiGroups: 595 | - "" 596 | resources: 597 | - namespaces 598 | verbs: 599 | - get 600 | - list 601 | - watch 602 | - apiGroups: 603 | - "" 604 | resources: 605 | - nodes 606 | verbs: 607 | - get 608 | - list 609 | - watch 610 | - apiGroups: 611 | - "" 612 | resources: 613 | - pods 614 | verbs: 615 | - get 616 | - list 617 | - watch 618 | - apiGroups: 619 | - "" 620 | resources: 621 | - pods/status 622 | verbs: 623 | - patch 624 | - update 625 | - apiGroups: 626 | - "" 627 | resources: 628 | - secrets 629 | verbs: 630 | - get 631 | - list 632 | - watch 633 | - apiGroups: 634 | - "" 635 | resources: 636 | - services 637 | verbs: 638 | - get 639 | - list 640 | - patch 641 | - update 642 | - watch 643 | - apiGroups: 644 | - "" 645 | resources: 646 | - services/status 647 | verbs: 648 | - patch 649 | - update 650 | - apiGroups: 651 | - elbv2.k8s.aws 652 | resources: 653 | - ingressclassparams 654 | verbs: 655 | - get 656 | - list 657 | - watch 658 | - apiGroups: 659 | - elbv2.k8s.aws 660 | resources: 661 | - targetgroupbindings 662 | verbs: 663 | - create 664 | - delete 665 | - get 666 | - list 667 | - patch 668 | - update 669 | - watch 670 | - apiGroups: 671 | - elbv2.k8s.aws 672 | resources: 673 | - targetgroupbindings/status 674 | verbs: 675 | - patch 676 | - update 677 | - apiGroups: 678 | - extensions 679 | resources: 680 | - ingresses 681 | verbs: 682 | - get 683 | - list 684 | - patch 685 | - update 686 | - watch 687 | - apiGroups: 688 | - extensions 689 | resources: 690 | - ingresses/status 691 | verbs: 692 | - patch 693 | - update 694 | - apiGroups: 695 | - networking.k8s.io 696 | resources: 697 | - ingressclasses 698 | verbs: 699 | - get 700 | - list 701 | - watch 702 | - apiGroups: 703 | - networking.k8s.io 704 | resources: 705 | - ingresses 706 | verbs: 707 | - get 708 | - list 709 | - patch 710 | - update 711 | - watch 712 | - apiGroups: 713 | - networking.k8s.io 714 | resources: 715 | - ingresses/status 716 | verbs: 717 | - patch 718 | - update 719 | --- 720 | apiVersion: rbac.authorization.k8s.io/v1 721 | kind: RoleBinding 722 | metadata: 723 | labels: 724 | app.kubernetes.io/name: aws-load-balancer-controller 725 | name: aws-load-balancer-controller-leader-election-rolebinding 726 | namespace: kube-system 727 | roleRef: 728 | apiGroup: rbac.authorization.k8s.io 729 | kind: Role 730 | name: aws-load-balancer-controller-leader-election-role 731 | subjects: 732 | - kind: ServiceAccount 733 | name: aws-load-balancer-controller 734 | namespace: kube-system 735 | --- 736 | apiVersion: rbac.authorization.k8s.io/v1 737 | kind: ClusterRoleBinding 738 | metadata: 739 | labels: 740 | app.kubernetes.io/name: aws-load-balancer-controller 741 | name: aws-load-balancer-controller-rolebinding 742 | roleRef: 743 | apiGroup: rbac.authorization.k8s.io 744 | kind: ClusterRole 745 | name: aws-load-balancer-controller-role 746 | subjects: 747 | - kind: ServiceAccount 748 | name: aws-load-balancer-controller 749 | namespace: kube-system 750 | --- 751 | apiVersion: v1 752 | kind: Service 753 | metadata: 754 | labels: 755 | app.kubernetes.io/name: aws-load-balancer-controller 756 | name: aws-load-balancer-webhook-service 757 | namespace: kube-system 758 | spec: 759 | ports: 760 | - port: 443 761 | targetPort: 9443 762 | selector: 763 | app.kubernetes.io/component: controller 764 | app.kubernetes.io/name: aws-load-balancer-controller 765 | --- 766 | apiVersion: apps/v1 767 | kind: Deployment 768 | metadata: 769 | labels: 770 | app.kubernetes.io/component: controller 771 | app.kubernetes.io/name: aws-load-balancer-controller 772 | name: aws-load-balancer-controller 773 | namespace: kube-system 774 | spec: 775 | replicas: 1 776 | selector: 777 | matchLabels: 778 | app.kubernetes.io/component: controller 779 | app.kubernetes.io/name: aws-load-balancer-controller 780 | template: 781 | metadata: 782 | labels: 783 | app.kubernetes.io/component: controller 784 | app.kubernetes.io/name: aws-load-balancer-controller 785 | spec: 786 | containers: 787 | - args: 788 | - --cluster-name=robin-personal-cluster 789 | - --ingress-class=alb 790 | image: amazon/aws-alb-ingress-controller:v2.2.0 791 | livenessProbe: 792 | failureThreshold: 2 793 | httpGet: 794 | path: /healthz 795 | port: 61779 796 | scheme: HTTP 797 | initialDelaySeconds: 30 798 | timeoutSeconds: 10 799 | name: controller 800 | ports: 801 | - containerPort: 9443 802 | name: webhook-server 803 | protocol: TCP 804 | resources: 805 | limits: 806 | cpu: 200m 807 | memory: 500Mi 808 | requests: 809 | cpu: 100m 810 | memory: 200Mi 811 | securityContext: 812 | allowPrivilegeEscalation: false 813 | readOnlyRootFilesystem: true 814 | runAsNonRoot: true 815 | volumeMounts: 816 | - mountPath: /tmp/k8s-webhook-server/serving-certs 817 | name: cert 818 | readOnly: true 819 | priorityClassName: system-cluster-critical 820 | securityContext: 821 | fsGroup: 1337 822 | serviceAccountName: aws-load-balancer-controller 823 | terminationGracePeriodSeconds: 10 824 | volumes: 825 | - name: cert 826 | secret: 827 | defaultMode: 420 828 | secretName: aws-load-balancer-webhook-tls 829 | --- 830 | apiVersion: cert-manager.io/v1alpha2 831 | kind: Certificate 832 | metadata: 833 | labels: 834 | app.kubernetes.io/name: aws-load-balancer-controller 835 | name: aws-load-balancer-serving-cert 836 | namespace: kube-system 837 | spec: 838 | dnsNames: 839 | - aws-load-balancer-webhook-service.kube-system.svc 840 | - aws-load-balancer-webhook-service.kube-system.svc.cluster.local 841 | issuerRef: 842 | kind: Issuer 843 | name: aws-load-balancer-selfsigned-issuer 844 | secretName: aws-load-balancer-webhook-tls 845 | --- 846 | apiVersion: cert-manager.io/v1alpha2 847 | kind: Issuer 848 | metadata: 849 | labels: 850 | app.kubernetes.io/name: aws-load-balancer-controller 851 | name: aws-load-balancer-selfsigned-issuer 852 | namespace: kube-system 853 | spec: 854 | selfSigned: {} 855 | --- 856 | apiVersion: admissionregistration.k8s.io/v1 857 | kind: MutatingWebhookConfiguration 858 | metadata: 859 | annotations: 860 | cert-manager.io/inject-ca-from: kube-system/aws-load-balancer-serving-cert 861 | labels: 862 | app.kubernetes.io/name: aws-load-balancer-controller 863 | name: aws-load-balancer-webhook 864 | webhooks: 865 | - admissionReviewVersions: 866 | - v1beta1 867 | clientConfig: 868 | service: 869 | name: aws-load-balancer-webhook-service 870 | namespace: kube-system 871 | path: /mutate-v1-pod 872 | failurePolicy: Fail 873 | name: mpod.elbv2.k8s.aws 874 | namespaceSelector: 875 | matchExpressions: 876 | - key: elbv2.k8s.aws/pod-readiness-gate-inject 877 | operator: In 878 | values: 879 | - enabled 880 | objectSelector: 881 | matchExpressions: 882 | - key: app.kubernetes.io/name 883 | operator: NotIn 884 | values: 885 | - aws-load-balancer-controller 886 | rules: 887 | - apiGroups: 888 | - "" 889 | apiVersions: 890 | - v1 891 | operations: 892 | - CREATE 893 | resources: 894 | - pods 895 | sideEffects: None 896 | - admissionReviewVersions: 897 | - v1beta1 898 | clientConfig: 899 | service: 900 | name: aws-load-balancer-webhook-service 901 | namespace: kube-system 902 | path: /mutate-elbv2-k8s-aws-v1beta1-targetgroupbinding 903 | failurePolicy: Fail 904 | name: mtargetgroupbinding.elbv2.k8s.aws 905 | rules: 906 | - apiGroups: 907 | - elbv2.k8s.aws 908 | apiVersions: 909 | - v1beta1 910 | operations: 911 | - CREATE 912 | - UPDATE 913 | resources: 914 | - targetgroupbindings 915 | sideEffects: None 916 | --- 917 | apiVersion: admissionregistration.k8s.io/v1 918 | kind: ValidatingWebhookConfiguration 919 | metadata: 920 | annotations: 921 | cert-manager.io/inject-ca-from: kube-system/aws-load-balancer-serving-cert 922 | labels: 923 | app.kubernetes.io/name: aws-load-balancer-controller 924 | name: aws-load-balancer-webhook 925 | webhooks: 926 | - admissionReviewVersions: 927 | - v1beta1 928 | clientConfig: 929 | service: 930 | name: aws-load-balancer-webhook-service 931 | namespace: kube-system 932 | path: /validate-elbv2-k8s-aws-v1beta1-targetgroupbinding 933 | failurePolicy: Fail 934 | name: vtargetgroupbinding.elbv2.k8s.aws 935 | rules: 936 | - apiGroups: 937 | - elbv2.k8s.aws 938 | apiVersions: 939 | - v1beta1 940 | operations: 941 | - CREATE 942 | - UPDATE 943 | resources: 944 | - targetgroupbindings 945 | sideEffects: None 946 | - admissionReviewVersions: 947 | - v1beta1 948 | clientConfig: 949 | service: 950 | name: aws-load-balancer-webhook-service 951 | namespace: kube-system 952 | path: /validate-networking-v1beta1-ingress 953 | failurePolicy: Fail 954 | matchPolicy: Equivalent 955 | name: vingress.elbv2.k8s.aws 956 | rules: 957 | - apiGroups: 958 | - networking.k8s.io 959 | apiVersions: 960 | - v1beta1 961 | operations: 962 | - CREATE 963 | - UPDATE 964 | resources: 965 | - ingresses 966 | sideEffects: None 967 | --------------------------------------------------------------------------------