0. Master Node + Worker Node cần bao nhiêu RAM?
Master Node = 1500 MB RAM
Worker Node = 1024 MB RAM
→ kiểm tra thì nằm ở đây
1. Chạy LAB
Copy 6 lệnh dưới → dán trên PowerShell bằng cách click chuột phải
→ không phải gõ gõ từng lệnh mất thời gian
Chạy 6 lệnh sau trên Powershell quyền Administrator → dấu # là giải thích (comment)
# Giả sử có ổ đĩa D:
# Tạo thư mục D:ansible-lab01 + chuyển vào thư mục
mkdir D:k8s-vb > $null ; cd D:k8s-vb
# Khai báo biến là link tới file cần download
$URL="https://devsecops.edu.vn/wp-content/uploads/2023/11/k8s-vb-J8IERtJQantocSqAH6LTOSfeFxoPfE.zip"
# Download file zìa
Invoke-WebRequest -URI $URL -OutFile k8s-vb.zip
# Giải nén file + đổi tên
Expand-Archive k8s-vb.zip -DestinationPath .
# Coi trong thư mục đang đứng có gì
dir
# Tạo máy ảo + chạy LAB từ A tới Á
vagrant up
Móc vào K8S dashboard bằng Nodeport → sinh ra port ngẫu nhiên 31808 → bạn chạy sẽ sinh ra port khác
→ chỉnh port forwarding 31808 trên máy ảo K8S Master Node 1 ra máy Host
Truy cập web trên máy Host – Windows 10/11
2. Các file nội dung mới nhất ở đây
Vagrantfile
Vagrant.configure("2") do |config|
config.vm.define "worker1" do |worker1|
worker1.vm.box = "ubuntu/jammy64"
worker1.vm.network "private_network", ip: "192.168.10.2", virtualbox__intnet: "mynetwork"
worker1.vm.hostname = "worker1"
worker1.vm.provider "virtualbox" do |v|
v.gui = true
v.name = "K8S Worker Node 1"
v.memory = 2048
v.cpus = 2
end
worker1.vm.provision "shell", path: "gen-key-pair.sh"
worker1.vm.provision "shell", path: "import-pub-key.sh"
end
config.vm.define "worker2" do |worker2|
worker2.vm.box = "ubuntu/jammy64"
worker2.vm.network "private_network", ip: "192.168.10.3", virtualbox__intnet: "mynetwork"
worker2.vm.hostname = "worker2"
worker2.vm.provider "virtualbox" do |v|
v.gui = true
v.name = "K8S Worker Node 2"
v.memory = 2048
v.cpus = 2
end
worker2.vm.provision "shell", path: "import-pub-key.sh"
end
config.vm.define "master1" do |master1|
master1.vm.box = "ubuntu/jammy64"
master1.vm.hostname = "master1"
master1.vm.network "private_network", ip: "192.168.10.8", virtualbox__intnet: "mynetwork"
master1.vm.provider "virtualbox" do |v|
v.gui = true
v.name = "K8S Master Node 1"
v.memory = 3072
v.cpus = 4
end
master1.vm.provision "shell", path: "import-key-pair.sh"
master1.vm.provision "shell", path: "k8s-master-config.sh"
master1.vm.provision "shell", path: "k8s-kubespray-deploy.sh"
master1.vm.provision "shell", path: "k8s-dashboard-config.sh"
end
end
gen-key-pair.sh
#!/bin/bash
echo -e "nSinh ra 1 cặp khóa riêng/chung (private/public key)n"
ssh-keygen -q -t rsa -b 2048 -N '' -C 'DevSecOps.EDU.VN' -f /vagrant/private_key_rsa
import-pub-key.sh
#!/bin/bash
echo -e "nGhi pub key vào user rootn"
cat /vagrant/private_key_rsa.pub > ~/.ssh/authorized_keys
import-key-pair.sh
#!/bin/bash
# Ghi private key vào user root
cp /vagrant/private_key_rsa ~/.ssh/
chmod 600 ~/.ssh/private_key_rsa
# Ghi public key vào user root
cat /vagrant/private_key_rsa.pub > ~/.ssh/authorized_keys
k8s-master-config.sh
#!/bin/bash
echo -e "nCài các gói cần thiếtn"
apt update
export DEBIAN_FRONTEND=noninteractive
apt install -y git python3 python3-pip wget
echo -e "nCài các thư viện Python cần thiết cho Kubesprayn"
cd
git clone https://github.com/kubernetes-sigs/kubespray.git
cd kubespray
pip install -r requirements.txt
ansible --version
echo -e "nChép các file config mẫu vàon"
cp -r inventory/sample inventory/mycluster
echo -e "nChép file Ansible Inventory vàon"
cp -f /vagrant/hosts.yml inventory/mycluster/
echo -e "nBật các chức năng của K8Sn"
# https://github.com/kubernetes-sigs/kubespray/blob/master/inventory/sample/group_vars/k8s_cluster/k8s-cluster.yml
sed -i 's/^kube_version:.*/kube_version: v1.28.4/' inventory/mycluster/group_vars/k8s_cluster/k8s-cluster.yml
sed -i 's/^kubernetes_audit.*/kubernetes_audit: true/' inventory/mycluster/group_vars/k8s_cluster/k8s-cluster.yml
sed -i 's/^#.*kubectl_localhost:.*/kubectl_localhost: true/' inventory/mycluster/group_vars/k8s_cluster/k8s-cluster.yml
sed -i 's/^#.*dashboard_enabled.*/dashboard_enabled: true/' inventory/mycluster/group_vars/k8s_cluster/addons.yml
sed -i 's/^ingress_nginx_enabled.*/ingress_nginx_enabled: true/' inventory/mycluster/group_vars/k8s_cluster/addons.yml
sed -i 's/^helm_enabled.*/helm_enabled: true/' inventory/mycluster/group_vars/k8s_cluster/addons.yml
sed -i 's/^metrics_server_enabled:.*/metrics_server_enabled: true/' inventory/mycluster/group_vars/k8s_cluster/addons.yml
k8s-kubespray-deploy.sh
#!/bin/bash
echo -e "nBuild K8S Cluster = Kubesprayn"
cd /root/kubespray
ansible-playbook -i inventory/mycluster/hosts.yml cluster.yml --private-key=~/.ssh/private_key_rsa
k8s-dashboard-config.sh
#!/bin/bash
echo -e "nBật K8S Dashboardn"
kubectl apply -f /vagrant/dashboard/dashboard-adminuser.yaml
kubectl apply -f /vagrant/dashboard/admin-role-binding.yaml
echo -e "nTruy cập K8S Dashboard = Nodeportn"
kubectl patch service kubernetes-dashboard -n kube-system -p '{"spec":{"type":"NodePort"}}'
# Lấy số port
port=$(kubectl get svc kubernetes-dashboard -n kube-system | grep NodePort | awk '{print $5}' | cut -f2 -d':' | cut -f1 -d'/')
echo -e "nnK8S Dashboard: https://127.0.0.1:$portn"
kubectl -n kube-system create token admin-user > /vagrant/token.txt
echo -e "nToken nằm ở /vagrant/token.txtn"
cat /vagrant/token.txt ; echo
echo -e "n--- Hết òi ---"
echo -e "n--- DevSecOps.Edu.VN mần cái này ---n"
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kube-system
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kube-system
Vagrant.configure("2") do |config|
config.vm.define "worker1" do |worker1|
worker1.vm.box = "ubuntu/jammy64"
worker1.vm.network "private_network", ip: "192.168.10.2", virtualbox__intnet: "mynetwork"
worker1.vm.hostname = "worker1"
worker1.vm.provider "virtualbox" do |v|
v.gui = true
v.name = "K8S Worker Node 1"
v.memory = 2048
v.cpus = 2
end
worker1.vm.provision "shell", path: "gen-key-pair.sh"
worker1.vm.provision "shell", path: "import-pub-key.sh"
end
config.vm.define "worker2" do |worker2|
worker2.vm.box = "ubuntu/jammy64"
worker2.vm.network "private_network", ip: "192.168.10.3", virtualbox__intnet: "mynetwork"
worker2.vm.hostname = "worker2"
worker2.vm.provider "virtualbox" do |v|
v.gui = true
v.name = "K8S Worker Node 2"
v.memory = 2048
v.cpus = 2
end
worker2.vm.provision "shell", path: "import-pub-key.sh"
end
config.vm.define "worker3" do |worker3|
worker3.vm.box = "ubuntu/jammy64"
worker3.vm.network "private_network", ip: "192.168.10.4", virtualbox__intnet: "mynetwork"
worker3.vm.hostname = "worker3"
worker3.vm.provider "virtualbox" do |v|
v.gui = true
v.name = "K8S Worker Node 3"
v.memory = 2048
v.cpus = 2
end
worker3.vm.provision "shell", path: "import-pub-key.sh"
end
config.vm.define "master1" do |master1|
master1.vm.box = "ubuntu/jammy64"
master1.vm.hostname = "master1"
master1.vm.network "private_network", ip: "192.168.10.8", virtualbox__intnet: "mynetwork"
master1.vm.provider "virtualbox" do |v|
v.gui = true
v.name = "K8S Master Node 1"
v.memory = 3072
v.cpus = 4
end
master1.vm.provision "shell", path: "import-key-pair.sh"
master1.vm.provision "shell", path: "k8s-master-config.sh"
master1.vm.provision "shell", path: "k8s-kubespray-deploy.sh"
master1.vm.provision "shell", path: "k8s-dashboard-config.sh"
master1.vm.provision "add-worker-node", type: "shell", path: "add-worker-node/k8s-add-worker-node.sh", run: "never"
end
end
#!/bin/bash
cd ~/kubespray
cp /vagrant/add-worker-node/hosts-add-worker-node.yml inventory/mycluster/
ansible-playbook -i inventory/mycluster/hosts-add-worker-node.yml cluster.yml --limit worker3 --private-key=~/.ssh/private_key_rsa
all:
hosts:
master1:
ansible_host: 192.168.10.8
ip: 192.168.10.8
access_ip: 192.168.10.8
worker1:
ansible_host: 192.168.10.2
ip: 192.168.10.2
access_ip: 192.168.10.2
worker2:
ansible_host: 192.168.10.3
ip: 192.168.10.3
access_ip: 192.168.10.3
worker3:
ansible_host: 192.168.10.4
ip: 192.168.10.4
access_ip: 192.168.10.4
children:
kube_control_plane:
hosts:
master1:
kube_node:
hosts:
worker1:
worker2:
worker3:
etcd:
hosts:
master1:
k8s_cluster:
children:
kube_control_plane:
kube_node:
calico_rr:
hosts: {}
Vagrant.configure("2") do |config|
config.vm.define "worker1" do |worker1|
worker1.vm.box = "ubuntu/jammy64"
worker1.vm.network "private_network", ip: "192.168.10.2", virtualbox__intnet: "mynetwork"
worker1.vm.hostname = "worker1"
worker1.vm.provider "virtualbox" do |v|
v.gui = true
v.name = "K8S Worker Node 1"
v.memory = 2048
v.cpus = 2
end
worker1.vm.provision "shell", path: "gen-key-pair.sh"
worker1.vm.provision "shell", path: "import-pub-key.sh"
end
config.vm.define "worker2" do |worker2|
worker2.vm.box = "ubuntu/jammy64"
worker2.vm.network "private_network", ip: "192.168.10.3", virtualbox__intnet: "mynetwork"
worker2.vm.hostname = "worker2"
worker2.vm.provider "virtualbox" do |v|
v.gui = true
v.name = "K8S Worker Node 2"
v.memory = 2048
v.cpus = 2
end
worker2.vm.provision "shell", path: "import-pub-key.sh"
end
config.vm.define "worker3" do |worker3|
worker3.vm.box = "ubuntu/jammy64"
worker3.vm.network "private_network", ip: "192.168.10.4", virtualbox__intnet: "mynetwork"
worker3.vm.hostname = "worker3"
worker3.vm.provider "virtualbox" do |v|
v.gui = true
v.name = "K8S Worker Node 3"
v.memory = 2048
v.cpus = 2
end
worker3.vm.provision "shell", path: "import-pub-key.sh"
end
config.vm.define "master1" do |master1|
master1.vm.box = "ubuntu/jammy64"
master1.vm.hostname = "master1"
master1.vm.network "private_network", ip: "192.168.10.8", virtualbox__intnet: "mynetwork"
master1.vm.provider "virtualbox" do |v|
v.gui = true
v.name = "K8S Master Node 1"
v.memory = 3072
v.cpus = 4
end
master1.vm.provision "shell", path: "import-key-pair.sh"
master1.vm.provision "shell", path: "k8s-master-config.sh"
master1.vm.provision "shell", path: "k8s-kubespray-deploy.sh"
master1.vm.provision "shell", path: "k8s-dashboard-config.sh"
master1.vm.provision "add-worker-node", type: "shell", path: "add-worker-node/k8s-add-worker-node.sh", run: "never"
master1.vm.provision "add-master-node", type: "shell", path: "add-master-node/k8s-add-master-node.sh", run: "never"
master1.vm.provision "deploy-app-cli", type: "shell", path: "deploy-app-cli/deploy-cli.sh", run: "never"
master1.vm.provision "connect-app-deployed-cli", type: "shell", path: "deploy-app-cli/connect-web-deployed-cli.sh", run: "never"
master1.vm.provision "deploy-app-yaml", type: "shell", path: "deploy-app-yaml/deploy-yaml-cli.sh", run: "never"
master1.vm.provision "connect-app-deployed-yaml", type: "shell", path: "deploy-app-yaml/connect-web-deployed-yaml.sh", run: "never"
end
config.vm.define "master2" do |master2|
master2.vm.box = "ubuntu/jammy64"
master2.vm.hostname = "master2"
master2.vm.network "private_network", ip: "192.168.10.9", virtualbox__intnet: "mynetwork"
master2.vm.provider "virtualbox" do |v|
v.gui = true
v.name = "K8S Master Node 2"
v.memory = 3072
v.cpus = 4
end
master2.vm.provision "shell", path: "import-pub-key.sh"
end
end
#!/bin/bash
cd ~/kubespray
cp /vagrant/add-master-node/hosts-add-master-node.yml inventory/mycluster/
ansible-playbook -i inventory/mycluster/hosts-add-master-node.yml cluster.yml --private-key=~/.ssh/private_key_rsa
all:
hosts:
master1:
ansible_host: 192.168.10.8
ip: 192.168.10.8
access_ip: 192.168.10.8
master2:
ansible_host: 192.168.10.9
ip: 192.168.10.9
access_ip: 192.168.10.9
worker1:
ansible_host: 192.168.10.2
ip: 192.168.10.2
access_ip: 192.168.10.2
worker2:
ansible_host: 192.168.10.3
ip: 192.168.10.3
access_ip: 192.168.10.3
worker3:
ansible_host: 192.168.10.4
ip: 192.168.10.4
access_ip: 192.168.10.4
children:
kube_control_plane:
hosts:
master1:
master2:
kube_node:
hosts:
worker1:
worker2:
worker3:
etcd:
hosts:
master1:
k8s_cluster:
children:
kube_control_plane:
kube_node:
calico_rr:
hosts: {}
#!/bin/bash
kubectl create deployment nginx-webserver --image=nginx --replicas=3
kubectl expose deployment nginx-webserver --type NodePort --port=80
kubectl get deployments.apps
kubectl get pods
kubectl get svc nginx-webserver
# END
#!/bin/bash
echo -e "nCoi App đã Deploy = CLI trên 3 Worker Noden"
export port=$(kubectl describe service nginx-webserver | grep ^NodePort | awk '{ print $3 }' | cut -f1 -d'/')
for i in {2..4}
do
echo -e "n192.168.10.$i:$portn";
curl -s 192.168.10.$i:$port | head -4;
echo -e "n------n";
done
# END
#!/bin/bash
kubectl apply -f /vagrant/deploy-app-yaml/apache-webserver.yaml
kubectl get svc apache-webserver
# END
#!/bin/bash
echo -e "nCoi App đã Deploy = YAML trên 3 Worker Noden"
for i in {2..4}
do
echo -e "n192.168.10.$i:30409n";
curl -s 192.168.10.$i:30409;
echo -e "n------n";
done
echo
# END
apiVersion: apps/v1
kind: Deployment
metadata:
name: apache-webserver
labels:
app: web
spec:
selector:
matchLabels:
app: web
replicas: 3
template:
metadata:
labels:
app: web
spec:
containers:
- name: apache-webserver
image: httpd
ports:
- containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
name: apache-webserver
labels:
app: apache-webserver
spec:
type: NodePort
selector:
app: web
ports:
- nodePort: 30409
port: 8080
targetPort: 80