Giới thiệu và cài đặt Kubernetes Cluster

Kubernetes là công cụ quản lý các ứng dụng container hóa chạy trên các công cụ như Docker, các bước để cài đặt Kubernetes trên máy trạm để thực hành và Kubernetes hoàn chỉnh để triển khai thực tế

Kubernetes là gì? Khái niệm!

Kubernetes (còn gọi là k8s) là một hệ thống để chạy, quản lý, điều phối các ứng dụng được
container hóa trên một cụm máy (1 hay nhiều) gọi là cluster.
Với Kubernetes bạn có thể cấu hình để chạy các ứng dụng, dịch vụ sao cho phù hợp nhất khi chúng tương tác với
nhau cũng như với bên ngoài. Bạn có thể điều chỉnh tăng giảm tài nguyên, bản chạy phục vụ cho dịch vụ (scale), bạn
có thể cập nhật (update), thu hồi update khi có vấn đề … Kubernetes là một công cụ mạnh mẽ, mềm dẻo, dễ mở rộng
khi so sánh nó với công cụ tương tự là Docker Swarm!

Kubernetes nó tương tác với các hệ thống cho phép chạy ứng dụng được container hóa và
có các API phù hợp giao giao tiếp với Kubernetes (như
Docker
containerd
cri-o
rktlet
), trong phạm vi các bài viết này sẽ chọn trường hợp phổ biến
là dùng Kubernetes với các máy cài đặt Docker.
Bạn cần học Docker trước khi học Kubernetes – Xem
Sử dụng Docker

Kubernetes được thiết kế bởi Google, về ngữ nghĩa thì tên này là tiếng Hy Lạp có nghĩa là tài công.

Sơ lược kiến trúc – các thành phần của Kubernetes

Hệ thống Kubernetes thật sự phức tạp, các thành phần của sẽ được tìm hiểu dần qua từng bài viết, nhưng ở đây
có một sơ đồ và một vài khái quát ban đầu về kiến trúc / thành phần của nó

kubernetes

Master Server là máy chính của cluster, tại đây điều khiển cả cụm máy.

etct là thành phần cơ bản cần thiết cho Kubernetes, nó lưu trữ các cấu hình chung cho cả cụm máy,
etct chạy tại máy master.
etct là một dự án nguồn mở (xem tại etcd) nó cung cấp dịch vụ
lưu dữ liệu theo cặp key/value

kube-apiserver chạy tại máy master, cung cấp các API Restful để các client (như kubectl) tương
tác với Kubernetes

kube-scheduler chạy tại master, thành phần này giúp lựa chọn Node nào để chạy các ứng dụng căn
cứ vào tài nguyên và các thành phần khác sao cho hệ thống ổn định.

kube-controller chạy tại master, nó điều khiển trạng thái cluster, tương tác để thực hiện các tác
vụ tạo, xóa, cập nhật … các tài nguyên

Kubelet dịch vụ vụ chạy trên tất cả các máy (Node), nó đảm đương giám sát chạy, dừng, duy trì các ứng
dụng chạy trên node của nó.

Kube-proxy:
cung cấp mạng proxy để các ứng dụng nhận được traffic từ ngoài mạng vào cluster.

Tạo Cluster Kubernetes

Để có một Kubernetes cần có các máy chủ (ít nhất một máy), trên các máy cài đặt Docker và Kubernetes. Một máy
khởi tạo là master và các máy khác là worker kết nối vào. Có nhiều cách để có Cluster Kubernetes, như cài đặt
minikube để có kubernetes một nút (node) để thực hành (môi trường chạy thử), hay dùng ngay Kubernetes trong
Docker Desktop, hay cài đặt một hệ thống đầy đủ (Cài Docker, Cài và khởi tạo Cluster Kubernetes), hay mua
từ các nhà cung cấp dịch vụ như Google Cloud Platform, AWS, Azuze …

Ở đây, giới thiệu hai cách một là nếu muốn đơn giản – cluster một nút thì dùng ngay từ Docker Destop để thử nghiệm.
Hai là cài đặt đầy đủ một hệ thống – cách mà triển khai product sẽ áp dụng.

Tạo Cluster Kubernetes từ Docker Desktop

Đây là cách đơn giản, nhanh chóng để có Cluster Kubernetes, vì Docker Destop các phiên bản mới đã tích hợp
sẵn, việc của bạn chỉ đơn giản là kích hoạt nó, chỉ có một hạn chế đó là Kubernetes chỉ có một Node,
loại này thích hợp để bạn chạy thủ các tính năng mà ngại cấu hình phức tạp

Để kích hoạt thì mở giao diện của Docker Destop nên (giống nhau cho cả bản Windows và macOS), rồi tại mục
Kubernetes chọn Enable Kubernetes rồi nhấn Apply vậy là máy của bạn đã có Cluster
Kubernetes

Kích hoạt Kubernetes trên macOS

kubernetes

Kích hoạt Kubernetes trên Windows

kubernetes

Sau khi kích hoạt bạn có thể thực hiện các lệnh sau để kiểu tra

# Lấy thông tin Cluster
kubectl cluster-info

# Các Node có trong Cluster
kubectl get nodes

kubernetes

kubectl là trình client, nó được sử dụng để kết nối và tương tác với Cluster Kubernetes. Đây là công cụ chính để làm việc với Kubernetes, các phần sau sẽ nói kỹ về nó!

Tạm thời đến đây bạn chỉ cần biết là kiểm tra để khẳng định đang có một Cluster trên máy của bạn!

Tạo Cluster Kubernetes hoàn chỉnh

Phần này sẽ tạo ra một Cluster Kubernetes hoàn chỉnh từ 3 máy (3 VPS – hay 3 Server) chạy CentOS, bạn có thể dùng cách
này khi triển khai môi trường product. Hệ thống này gồm:

Tên máy/Hostname
Thông tin hệ thống
Vai trò

master.xtl
HĐH CentOS7, Docker CE, Kubernetes.
Địa chỉ IP 172.16.10.100
Khởi tạo là master

worker1.xtl
HĐH CentOS7, Docker CE, Kubernetes.
Địa chỉ IP 172.16.10.101
Khởi tạo là worker

worker2.xtl
HĐH CentOS7, Docker CE, Kubernetes.
Địa chỉ IP 172.16.10.102
Khởi tạo là worker

Để có hệ thống 3 máy trên khi chưa có điều kiện mua các VPS thực thụ thì sẽ dùng máy ảo VirtualBox. Bạn có thể
tải về hệ điều hành CentOS 7, cài đặt từng bước rồi tiến hành cấu hình. Tuy nhiên ở đây, nhằm nhanh chóng
sẽ sử dụng Vagrant giúp tự động hóa quá trình tạo 3 máy ảo trên VirtualBox (nếu bạn chưa biết
Vagrant thì xem: Sử dụng Vagrant trước).
Đây là quá trình cài đặt phức tạp, cố gắng thực hiện tuần tự từng bước!

Hãy tạo ra một thư mục đặt tên kubernetes-centos7 để chứa các file cấu hình Vagrant.

Tạo máy Master Kubernetes

Tạo thự mục con master, tạo trong nó file vagrantfile như sau:

kubernetes-centos7/master/Vagrantfile

# -*- mode: ruby -*-
# vi: set ft=ruby :

# Tạo máy ảo từ box centos/7, gán địa chỉ IP, đặt hostname, gán 2GB bộ nhớ, 2 cpus  
Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  config.vm.network "private_network", ip: "172.16.10.100"
  config.vm.hostname = "master.xtl"

  config.vm.provider "virtualbox" do |vb|
     vb.name = "master.xtl"
     vb.cpus = 2
     vb.memory = "2048"
  end
  
  # Chạy file install-docker-kube.sh sau khi nạp Box
  config.vm.provision "shell", path: "./../install-docker-kube.sh"

  # Chạy các lệnh shell
  config.vm.provision "shell", inline: <<-SHELL
    # Đặt pass 123 có tài khoản root và cho phép SSH
    echo "123" | passwd --stdin root
    sed -i 's/^PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config
    systemctl reload sshd
# Ghi nội dung sau ra file /etc/hosts để truy cập được các máy theo HOSTNAME
cat >>/etc/hosts<<EOF
172.16.10.100 master.xtl
172.16.10.101 worker1.xtl
172.16.10.102 worker2.xtl
EOF

  SHELL
end

kubernetes-centos7/install-docker-kube.sh

#!/bin/bash

# Cập nhật 12/2019

# Cai dat Docker
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum update -y && yum install docker-ce-18.06.2.ce -y
usermod -aG docker $(whoami)

## Create /etc/docker directory.
mkdir /etc/docker

# Setup daemon.
cat > /etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2",
  "storage-opts": [
    "overlay2.override_kernel_check=true"
  ]
}
EOF

mkdir -p /etc/systemd/system/docker.service.d


# Restart Docker
systemctl enable docker.service
systemctl daemon-reload
systemctl restart docker


# Tat SELinux
setenforce 0
sed -i --follow-symlinks 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/sysconfig/selinux

# Tat Firewall
systemctl disable firewalld >/dev/null 2>&1
systemctl stop firewalld

# sysctl
cat >>/etc/sysctl.d/kubernetes.conf<<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system >/dev/null 2>&1

# Tat swap
sed -i '/swap/d' /etc/fstab
swapoff -a

# Add yum repo file for Kubernetes
cat >>/etc/yum.repos.d/kubernetes.repo<<EOF
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF

yum install -y -q kubeadm kubelet kubectl

systemctl enable kubelet
systemctl start kubelet

# Configure NetworkManager before attempting to use Calico networking.
cat >>/etc/NetworkManager/conf.d/calico.conf<<EOF
[keyfile]
unmanaged-devices=interface-name:cali*;interface-name:tunl*
EOF

Thiết lập file chạy được

chmode +x install-docker-kube.sh

Tại thư mục kubernetes-centos7/master/ gõ lệnh vagrant để tạo máy master.xtl

vagrant up

Sau lệnh này, quá trình cài đặt diễn ra, kết thúc thì có máy ảo VirtualBox với tên master.xtl trong đó đã có
Docker, kubelet đang chạy ở địa chỉ IP 172.16.10.100, hãy ssh vào máy này bằng lệnh ssh với tài khoản
root có cấu hình pass là 123 ở trên.

Khởi tạo Cluster

Trong lệnh khởi tạo cluster có tham số --pod-network-cidr để chọn cấu hình mạng của POD,
do dự định dùng Addon calico nên chọn --pod-network-cidr=192.168.0.0/16

Gõ lệnh sau để khở tạo là nút master của Cluster

kubeadm init --apiserver-advertise-address=172.16.10.100 --pod-network-cidr=192.168.0.0/16

Sau khi lệnh chạy xong, chạy tiếp cụm lệnh nó yêu cầu chạy sau khi khởi tạo- để chép file cấu hình đảm bảo trình kubectl trên máy này
kết nối Cluster

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

Tiếp đó, nó yêu cầu cài đặt một Plugin mạng trong các Plugin tại addon, ở đây đã chọn calico, nên chạy lệnh sau để cài nó

kubectl apply -f https://docs.projectcalico.org/v3.10/manifests/calico.yaml

Gõ vài lệnh sau để kiểm tra

# Thông tin cluster
kubectl cluster-info
# Các node trong cluster
kubectl get nodes
# Các pod đang chạy trong tất cả các namespace
kubectl get pods -A

kubernetes

Vậy là đã có Cluster với 1 node!

Cấu hình kubectl máy trạm truy cập đến các Cluster

Chương trình client kubectl là công cụ dòng lệnh kết nối và tương tác với các Cluster Kubernetes,
thường khi cài đặt Kubernetes mọi người cũng cài luôn kubectl như phần trên trên, ngay cả máy
cài Docker Desktop cũng đã có kubectl.
Tất nhiên, bạn có cài đặt kubectl trên một máy không Docker, không Kubernetes với mục đích
chỉ dùng nó kết nối đến hệ thống Cluster từ xa. Nếu muốn cài ở máy độc lập như vậy
xem tại Intall kubectl

File cấu hình lệnh kubectl

Khi thi hành kubectl, thì nó đọc file cấu hình ở đường dẫn
$HOME/.kube/config để biết các thông số để kết nối đến Cluster.
($HOME là thư mục gốc dành cho user đang chạy,
để biết chính xác gõ lệnh echo $HOME) – tài khoản root thì đó là /root/.kube/config

Trở lại máy Host, để xem nội dung cấu hình kubectl gõ lệnh

kubectl config view

Tại máy master ở trên, có file cấu hình cho tại /root/.kube/config, ta copy file cấu hình này
ra lưu thành file config-mycluster (không ghi đè vào config hiện tại của máy HOST)

scp [email protected]:/etc/kubernetes/admin.conf ~/.kube/config-mycluster

(Nhớ thay đường dẫn theo user của bạn)

Vậy trên máy của tôi đang có 2 file cấu hình

  • /User/xuanthulab/.kube/config-mycluster cấu hình kết nối đến Cluster mới tạo ở trên
  • /User/xuanthulab/.kube/config cấu hình kết nối đến Cluster cục bộ của bản Kubernetes có sẵn
    của Docker

Nếu muốn yêu cầu kubectl sử dụng ngay file cấu hình nào đó, thì gán biến môi trường
KUBECONFIG bằng đường dẫn file cấu hình, ví dụ sử dụng file cấu hình config-mycluster

export KUBECONFIG=/Users/xuanthulab/.kube/config-mycluster

Sau lệnh đó thì kubectl sẽ dùng config-mycluster để có thông tin kết nối đến, nhưng trường hợp này
chỉ có hiệu lực trong một phiên làm việc, ví dụ nếu bạn đóng terminal và mở lại thì lại phải thiết lập
lại biến môi trường như trên.

Sử dụng các context trong cấu hình kubectl

(hãy tắt terminal và mở lại để KUBECONFIG không còn tác dụng)

Khi bạn xem nội dung config với lệnh kubectl config view, bạn thấy rằng nó khai báo có các mục
cluster là thông tin của cluster với tên, user thông tin user được đăng nhập,
context là ngữ cảnh sử dụng, mỗi ngữ cảnh có tên trong đó có thông tin user và cluster.

kubernetes

Ở file trên bạn thấy mục current-context là context với tên docker-desktop,
có nghĩa là kết nối đến cluster có tên docker-desktop với user là docker-desktop

Giờ bạn sẽ thực hiện kết hợp 2 file: config và config-mycluster thành 1 và lưu trở lại config.

export KUBECONFIG=~/.kube/config:~/.kube/config-mycluster
kubectl config view --flatten > ~/.kube/config_temp
mv ~/.kube/config_temp ~/.kube/config

Như vậy trong file cấu hình đã có các ngữ cảnh khác nhau để sử dụng, đóng terminal và mở lại rồi gõ
lệnh, có các ngữ cảnh nào

kubernetes

Ký hiệu * là cho biết context hiện tại, nếu muốn chuyển làm việc sang context có tên
kubernetes-admin@kubernetes (nối với cluster mới tạo ở trên) thì gõ lệnh

kubectl config use-context kubernetes-admin@kubernetes

Như vậy sử dụng context, giúp bạn lưu và chuyển đổi dễ dàng các loại
kết nối đến các cluster của bạn

Cài đặt các node worker – kubernetes

Tạo thư mục kubernetes-centos7/worker1kubernetes-centos7/worker2 để cấu hình,
tạo các file Vagrantfile trong thư mục tương ứng với nội dung

kubernetes-centos7/worker1/Vagrantfile

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  config.vm.network "private_network", ip: "172.16.10.101"
  config.vm.hostname = "worker1.xtl"

  config.vm.provider "virtualbox" do |vb|
     vb.name = "worker1.xtl"
     vb.cpus = 1
     vb.memory = "1024"
  end
   
  config.vm.provision "shell", path: "./../install-docker-kube.sh"

  config.vm.provision "shell", inline: <<-SHELL
  
    echo "root password"
    echo "123" | passwd --stdin root
    sed -i 's/^PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config
    systemctl reload sshd


cat >>/etc/hosts<<EOF
172.16.10.100 master.xtl
172.16.10.101 worker1.xtl
172.16.10.102 worker2.xtl
EOF

    
  SHELL
end

kubernetes-centos7/worker2/Vagrantfile

# -*- mode: ruby -*-
# vi: set ft=ruby :

# -*- mode: ruby -*-
# vi: set ft=ruby :
  
Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  config.vm.network "private_network", ip: "172.16.10.102"
  config.vm.hostname = "worker2.xtl"

  config.vm.provider "virtualbox" do |vb|
     vb.name = "worker2.xtl"
     vb.cpus = 1
     vb.memory = "1024"
  end
   
  config.vm.provision "shell", path: "./../install-docker-kube.sh"

  config.vm.provision "shell", inline: <<-SHELL
  
    echo "root password"
    echo "123" | passwd --stdin root
    sed -i 's/^PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config
    systemctl reload sshd
    

cat >>/etc/hosts<<EOF
172.16.10.100 master.xtl
172.16.10.101 worker1.xtl
172.16.10.102 worker2.xtl
EOF


  SHELL
end

Sau đó vào từng thư mục, thực hiện lệnh vagrant up để tạo hai máy ảo có cài đặt
docker và kubernetes, máy ảo có tên và ip tương ứng worker1.xtl (172.16.10.101), worker2.xtl (172.16.10.102)

Kết nối Node vào Cluster

Hãy vào máy node master (bằng SSH ssh [email protected]).
Thực hiện lệnh sau với Cluster để lấy lệnh kết nối

kubeadm token create --print-join-command

kubernetes

Nó cho nội dung lệnh kubeadm join ... thực hiện lệnh này trên các node worker thì node
worker sẽ nối vào Cluster

SSH vào máy worker1, work2 và thực hiện kết nối

kubernetes

Giờ kiểm tra các node có trong Cluster

kubectl get nodes

kubernetes

Tổng kết lại

Đến đây bạn đã biết khởi tạo một Cluster từ Docker Destop hay một Cluster phức tạp 3 node thực thụ, tuy nhiên
quá trình cài đặt vẫn chưa hoàn thành, các công cụ cần để dễ dàng làm việc với Kubernetes sẽ tiếp tục ở bài sau,
nhưng hiện giờ bạn đã biết các lệnh:

# khởi tạo một Cluster
kubeadm init --apiserver-advertise-address=172.16.10.100 --pod-network-cidr=192.168.0.0/16

# Cài đặt giao diện mạng calico sử dụng bởi các Pod
kubectl apply -f https://docs.projectcalico.org/v3.10/manifests/calico.yaml

# Thông tin cluster
kubectl cluster-info

# Các node (máy) trong cluster
kubectl get nodes

# Các pod (chứa container) đang chạy trong tất cả các namespace
kubectl get pods -A

# Xem nội dung cấu hình hiện tại của kubectl
kubectl config view

# Thiết lập file cấu hình kubectl sử dụng cho 1 phiên làm việc hiện tại của termianl
export KUBECONFIG=/Users/xuanthulab/.kube/config-mycluster

# Gộp file cấu hình kubectl
export KUBECONFIG=~/.kube/config:~/.kube/config-mycluster
kubectl config view --flatten > ~/.kube/config_temp
mv ~/.kube/config_temp ~/.kube/config

# Các ngữ cảnh hiện có trong config
kubectl config get-contexts

# Đổi ngữ cảnh làm việc (kết nối đến cluster nào)
kubectl config use-context kubernetes-admin@kubernetes

# Lấy mã kết nối vào Cluster
kubeadm token create --print-join-command

# node worker kết nối vào Cluster
kubeadm join 172.16.10.100:6443 --token 5ajhhs.atikwelbpr0 ...

ĐĂNG KÝ KÊNH, XEM CÁC VIDEO TRÊN XUANTHULAB

Đăng ký nhận bài viết mới