本人以前的實驗環境一直用的是OCP/OKD集羣,其搭建在PC Server服務器上,現須要在本身的windows工做站上搭建一個K8S集羣,首先想到的是使用CodeReady Container(CRC)來搭建一個OKD集羣,但其資源要求實在是過高(4C9G內存),且CRC所需的虛擬化軟件hyper-v與virshbox有衝突,鑑於此問題,雖然有minikube可供選擇,但本人決定手動搭建一個原生態K8S集羣。node
本人實驗環境爲virshbox安裝的一臺虛擬機,其操做系統版本爲Centos Linux 8,CPU 4個,內存4G,磁盤35G,其擁有兩塊網卡,網卡1鏈接到NAT網絡以便利用宿主機網絡鏈接英特網,而網卡2鏈接到Host-Only網絡,K8S API監聽在在此網絡上,主機名稱爲cts.zyl.io。linux
主機名 | 主機資源 | 網卡1 | 網卡2 |
---|---|---|---|
cts.zyl.io | 4C4G、Disk:35G | Nat網絡,dhcp獲取ip | Host-only網絡,靜態配置IP爲192.168.110.6 |
參考k8s官方文檔與cri-o官方文檔咱們先選擇一容器運行時,如做者對docker容器運行時實在不敢興趣1,故計劃安裝cri-o輕量級容器運行時,參考下圖,做者準備安裝k8s 1.18,故選擇cri-o 1.18.x。nginx
對於Centos Linux 8操做系統,執行以下命令安裝CRI-O容器運行時2:git
sudo dnf -y install 'dnf-command(copr)' sudo dnf -y copr enable rhcontainerbot/container-selinux sudo curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable.repo https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/CentOS_8/devel:kubic:libcontainers:stable.repo sudo curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable:cri-o:1.18.repo https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable:cri-o:1.18/CentOS_8/devel:kubic:libcontainers:stable:cri-o:1.18.repo sudo dnf -y install cri-o
注意:做者當前安裝crio-o 1.18.1時遇到一個bug:文件/etc/crio/crio.conf中的conmon路徑爲 /usr/libexec/crio/conmon
,但實際位置在/usr/bin/conmon
,因而執行以下命令調整配置後重啓crio進程。github
sed 's|/usr/libexec/crio/conmon|/usr/bin/conmon|' -i /etc/crio/crio.conf systemctl start crio.service
咱們安裝crio的管理工具crictl
3,kubeadm
會使用其拉取鏡像。docker
wget -O crictl.tgz https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.18.0/crictl-v1.18.0-linux-amd64.tar.gz tar -xf crictl.tgz mv crictl /usr/local/bin
以下所示,咱們爲docker.io與k8s.gcr.io配置mirror鏡像倉庫。注意:爲k8s.gcr.io配置鏡像倉庫很重要,雖然咱們可設置--image-repository registry.aliyuncs.com/google_containers
來告知kubeinit
從阿里雲鏡像倉庫下載鏡像,但本人發現部署Pod時仍使用k8s.gcr.io/pause鏡像,故爲了不所以產生報錯,此處爲其配置Mirror鏡像倉庫。shell
cat > /etc/containers/registries.conf <<EOF unqualified-search-registries = ["docker.io", "quay.io"] [[registry]] location = "docker.io" insecure = false blocked = false mirror-by-digest-only = false prefix = "" [[registry.mirror]] location = "docker.mirrors.ustc.edu.cn" insecure = false [[registry]] location = "k8s.gcr.io" insecure = false blocked = false mirror-by-digest-only = false prefix = "" [[registry.mirror]] location = "registry.aliyuncs.com/google_containers" insecure = false EOF
參考Network Plugins,當沒有爲kubelet配置cni網絡插件時,其使用的noop插件依賴於Linux bridge(網橋)在容器間傳輸流量,亦或者如docker、crio4默認的網絡插件一樣基於網橋傳輸流量,此時需加載br_netfilter
模塊並設置net.bridge.bridge-xxx=1
以便iptables能識別網橋傳輸的流量。注意:若後續咱們選擇的SDN網絡不依賴Linux網橋傳輸流量,則此處實際上可忽略,但配置上也沒任何問題。windows
# these persist across reboots. cat > /etc/modules-load.d/k8s.conf <<EOF overlay br_netfilter EOF modprobe overlay modprobe br_netfilter # Set up required sysctl params, these persist across reboots. cat > /etc/sysctl.d/99-kubernetes-cri.conf <<EOF net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1 net.bridge.bridge-nf-call-ip6tables = 1 EOF sysctl --system
上節已安裝了cri-o容器運行時,本節咱們將安裝kubeadm,但在此前,咱們參考官方文檔Installing kubeadm瞭解一些重要事項,並完善其餘所需步驟。api
cat /sys/class/dmi/id/product_uuid
);systemctl stop firewalld systemctl disable firewalld
kubeadm
會報錯。cat > /etc/sysctl.d/99-disable-swap.conf <<EOL vm.swappiness=0 EOL sysctl --system vi /etc/fstab # 註釋swap行
kubeadm
會報錯。setenforce 0 sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config
接着,執行以下命令安裝kubelet
、kubeadm
、kubectl
,然後設置kubelet
開機自啓動。安全
cat <<EOF > /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/ enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg exclude=kubelet kubeadm kubectl EOF yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes systemctl enable --now kubelet
注意:
kubeadm
初始化或加入現有k8s集羣。當前kubeadm僅能爲docker容器運行時自動檢測其cgroup driver,而對於咱們配置的crio容器運行時,則須要爲其手動配置cgroup驅動。
When using Docker, kubeadm will automatically detect the cgroup driver for the kubelet and set it in the/var/lib/kubelet/config.yaml
file during runtime....
The automatic detection of cgroup driver for other container runtimes like CRI-O and containerd is work in progress.
咱們配置的crio的cgroup驅動爲systemd而非cgroupfs,按照官方文檔所示需配置/var/lib/kubelet/config.yaml文件,於其中設置cgroupDriver: systemd
。
$ cat /etc/crio/crio.conf |grep systemd cgroup_manager = "systemd" $ mkdir -p /var/lib/kubelet $ cat > /var/lib/kubelet/config.yaml <<EOL apiVersion: kubelet.config.k8s.io/v1beta1 kind: KubeletConfiguration cgroupDriver: systemd EOL $ systemctl daemon-reload $ systemctl restart kubelet
可是,這裏有個問題,當執行kubeadm init
後不會保留cgroupDriver值,從而致使kubelet
調用crio
容器運行時異常,以下所示。
% journalctl -u kubelet -f ... RunPodSandbox from runtime service failed: rpc error: code = Unknown desc = cri-o configured with systemd cgroup manager, but did not receive slice as parent: /kubepods/besteffort/pod6407b05153e245d7313ea88bfb3be36a
鑑於此,雖然官方文檔不建議將參數配置於/etc/sysconfig/kubelet、/etc/default/kubelet或/var/lib/kubelet/kubeadm-flags.env中,但咱們仍然配置於此文件中:
cat > /etc/sysconfig/kubelet <<EOF KUBELET_EXTRA_ARGS=--cgroup-driver=systemd EOF
注意:「安裝容器運行時」一節有提到過,即便咱們在調用kubeadm init
時經過參數--image-repository
指定鏡像倉庫地址,但pause鏡像仍從k8s.gcr.io獲取從而致使異常,爲解決此問題,咱們在容器運行時爲k8s.gcr.io配置了鏡像倉庫,但還有一種方式可供選擇:調整kubelet配置指定pause鏡像。
# /etc/sysconfig/kubelet KUBELET_EXTRA_ARGS=--pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.2
參考官方文檔Creating a single control-plane cluster with kubeadm,咱們執行以下命令建立一個單節點k8s集羣。注意:其中--pod-network-cidr
設置的pod網段不該與現有網段重疊,即網段是當前空閒的,因虛擬機有兩塊網卡,其默認路由在nat網段上,爲了不集羣api server監控到nat所在的網卡上,此處經過--apiserver-advertise-address
指定apiserver使用host-only所在的網段。
kubeadm init \ --apiserver-advertise-address=192.168.110.6 \ --pod-network-cidr=10.254.0.0/16
若命令無報錯,成功後將顯示以下信息:
Your Kubernetes control-plane has initialized successfully! To start using your cluster, you need to run the following as a regular user: mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config You should now deploy a pod network to the cluster. Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at: https://kubernetes.io/docs/concepts/cluster-administration/addons/ Then you can join any number of worker nodes by running the following on each as root: kubeadm join 192.168.110.6:6443 --token nh1erl.d8eh61epm8s4y8oj \ --discovery-token-ca-cert-hash sha256:dce7e5ffc2d3d8662ab48bb1a3eae3fff8e0cbf65784295ac01cf631bbfe5ba1
咱們執行以下命令爲客戶端工具kubectl
配置上下文,其中文件/etc/kubernetes/admin.conf具有整個集羣管理員權限。
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
那麼此時,咱們可經過kubectl
檢查集羣狀態了,以下所示:
# 默認建立了4個命名空間: $ kubectl get namespaces NAME STATUS AGE default Active 54m kube-node-lease Active 54m kube-public Active 54m kube-system Active 54m # k8s系統組件所有至於kube-system命名空間中 $ kubectl get pod --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE kube-system coredns-66bff467f8-4hfws 1/1 Running 0 55m kube-system coredns-66bff467f8-rm5lp 1/1 Running 0 55m kube-system etcd-cts.zyl.io 1/1 Running 0 56m kube-system kube-apiserver-cts.zyl.io 1/1 Running 0 56m kube-system kube-controller-manager-cts.zyl.io 1/1 Running 0 56m kube-system kube-proxy-zcbjj 1/1 Running 0 55m kube-system kube-scheduler-cts.zyl.io 1/1 Running 0 56m
注意:etcd、kube-apiserver、kube-controller-manager、kube-scheduler組件爲靜態模式部署,其部署清單在主機的/etc/kubernetes/manifests目錄裏,kubelet會自動加載此目錄並啓動pod。
$ ls -l /etc/kubernetes/manifests/ -rw------- 1 root root 1858 Jun 8 20:33 etcd.yaml -rw------- 1 root root 2709 Jun 8 20:33 kube-apiserver.yaml -rw------- 1 root root 2565 Jun 8 20:33 kube-controller-manager.yaml -rw------- 1 root root 1120 Jun 8 20:33 kube-scheduler.yaml
coredns使用deployment部署,而kube-proxy使用daemonset模式部署:
$ kubectl get ds,deploy -n kube-system NAME DESIRED NODE SELECTOR AGE daemonset.apps/kube-proxy 1 ... kubernetes.io/os=linux 60m NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/coredns 2/2 2 2 60m
coredns部署了兩個pod,對於咱們單節點實驗環境來講不必,將其設置爲1:
kubectl scale deployment/coredns --replicas=1 -n kube-system
集羣還缺乏SDN網絡,咱們這裏選擇Calico,其不但具有高性能,且支持網絡策略。參考文檔Quickstart for Calico on Kubernetes,當系統配置NetworkManager管理網絡時,爲避免其影響Calico,配置以下文件告知NM不要管理Calico的網絡接口。
cat > /etc/NetworkManager/conf.d/calico.conf <<'EOF' [keyfile] unmanaged-devices=interface-name:cali*;interface-name:tunl* EOF
接着,咱們執行以下命令部署Calico。注意:除了直接使用部署清單部署calico外,咱們還可經過operator部署,項目地址爲tigera/operator。
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
執行以下等待其Pod運行正常:
$ watch kubectl get pods -n kube-system ... NAME READY STATUS RESTARTS AGE calico-kube-controllers-76d4774d89-bgt86 1/1 Running 0 15m calico-node-7gjls 1/1 Running 0 17m
控制節點默認不容許調度Pod,但對於咱們的單節點集羣來講,爲了測試咱們必需要讓控制節點可調度Pod,故執行以下命令放開此限制:
kubectl taint nodes --all node-role.kubernetes.io/master-
咱們已搭建了一個最基本的K8S集羣,其當前僅含K8S核心控制組件與Calico SDN網絡,雖然集羣僅有一個單節點,但因咱們配置Master可調度Pod,故此時咱們已經可部署測試應用了。
當前咱們位於default命名空間中,執行以下命令快速部署一個nginx:
kubectl create deployment nginx --image=nginx
此nginx部署僅含一個pod,以下所示:
$ kubectl get pod --show-labels -w NAME READY STATUS RESTARTS AGE LABELS nginx-f89759699-lrvzq 1/1 Running 1 15h app=nginx
獲取其IP地址並訪問:
$ kubectl describe pod -l app=nginx | grep ^IP: IP: 10.254.40.9 $ curl 10.254.40.9 ... <title>Welcome to nginx!</title>
爲deployment建立service:
$ kubectl expose deploy nginx --port=80 --target-port=80 $ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx ClusterIP 10.106.209.139 <none> 80/TCP 34m
參考這裏,kube-proxy使用ipvs模式在k8s v1.11時已GA,其相對於iptables具有更高的性能,但並非說iptables就沒有用了,實際上ipvs會與iptables聯合起效。
若咱們未執行kubeadm init
初始化集羣,則可經過以下方式設置kube-proxy使用ipvs模式:
cat > config.yml <<'EOF' kubeProxy: config: featureGates: SupportIPVSProxyMode: true mode: ipvs EOF kube init --config config.yml
對於已經在用的k8s集羣,咱們在各節點上執行以下命令加載ipvs模塊。注意:本人實驗環境發現下述模塊已被自動加載,若如此,則無需處理。
# 動態加載模塊 modprobe -- ip_vs modprobe -- ip_vs_rr modprobe -- ip_vs_wrr modprobe -- ip_vs_sh modprobe -- nf_conntrack # 確保開機時能加載模塊 cat > /etc/modules-load.d/ipvs.conf <<'EOF' ip_vs ip_vs_rr ip_vs_wrr ip_vs_sh nf_conntrack EOF
更新configmap,將mode調整爲ipvs:
$ kubectl edit cm -n kube-system kube-proxy ... mode: "ipvs" # 默認爲""(空)則爲iptables模式 ...
然後重啓kube-proxy,執行以下命令:
kubectl delete pod -n kube-system -l k8s-app=kube-proxy
最後,咱們安裝ipvsadm工具並可驗證service已被ipvs所配置。
$ yum -y install ipvsadm $ ipvsadm -ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 10.96.0.1:443 rr -> 192.168.110.6:6443 Masq 1 4 0 ...
對於生產環境,K8S集羣節點主機名應可供DNS域名解析出來,不然可能會因主機名沒法被解析而形成某些應用異常,如metrics-server,一樣,對於建立的Ingress所分配的域名,也應被DNS域名系統正確解析,不然咱們不得不手動爲每一個Ingress配置的主機名修改/etc/hosts文件已作靜態配置。
對於本文搭建的測試環境,咱們不在單獨配置額外的DNS域名系統,而是調整K8S集羣的CoreDNS域名系統,以下所示。
參考Custom DNS Entries For Kubernetes文章,咱們調整configmap:coredns,於其中添加一個zyl.io的Zonefile,而後於其中添加對cts.zyl.io主機的域名解析以及指定.app.zyl.io的一個DNS Wildcard。
$ kubectl -n kube-system edit cm coredns ... Corefile: | .:53 { ... file /etc/coredns/zone.zyl.io zyl.io } zone.zyl.io: | zyl.io. IN SOA root.zyl.io. root.zyl.io. 2020061113 7200 3600 1W 1D cts IN A 192.168.110.6 *.app.zyl.io. 300 IN A 192.168.110.6
然後,執行以下命令調整coredns部署,將zone.zyl.io掛載到容器中。
$ kubectl -n kube-system edit deployment coredns ... volumes: - configMap: defaultMode: 420 items: - key: Corefile path: Corefile - key: zone.zyl.io path: zone.zyl.io name: coredns name: config-volume
接着,啓動一個包含nslookup、host命令的容器進行測試:
$ kubectl run -it --rm --restart=Never --image-pull-policy='IfNotPresent' \ --image=infoblox/dnstools:latest dnstools dnstools# host cts cts.zyl.io has address 192.168.110.6 dnstools# host z.app.zyl.io z.app.zyl.io has address 192.168.110.6
爲了讓集羣外可以使用此dns域名系統,咱們可將其經過hostNetwork將端口映射出來:
$ kubectl -n kube-system edit deployment coredns ... hostNetwork: true ... $ netstat -an|grep 53|grep udp udp6 0 0 :::53 :::*
爲了完善集羣功能,本章介紹一些基本的附加組件,咱們可按需配置,如dashboard對咱們測試來講沒啥用,而ingress、持久化存儲比較有用。
經過Ingress咱們可將容器端口映射到集羣外,參考官方文檔Ingress Controllers此處咱們選擇Traefik控制器。
下面咱們使用helm v3來安裝traefik,故咱們首先安裝helm v3:
wget -O helm.tgz https://get.helm.sh/helm-v3.2.3-linux-amd64.tar.gz tar -xf helm.tgz mv linux-amd64/helm /usr/local/bin/ chmod 755 /usr/local/bin/helm
參考項目containous/traefik-helm-chart,執行以下命令將其安裝到獨立的traefik命名空間中。注意:這裏咱們設置hostNetwork=true
將端口以主機網絡映射到集羣外,而爲了訪問dashboard(爲了安全緣由默認未開放),此處咱們設置--api.insecure
參數。
helm repo add traefik https://containous.github.io/traefik-helm-chart cat > /tmp/values.yaml <<EOF podDisruptionBudget: enabled: true hostNetwork: true service: type: ClusterIP dashboard: ingressRoute: true ports: traefik: expose: true additionalArguments: - "--providers.kubernetesingress.ingressclass=traefik" - "--log.level=DEBUG" - "--api.insecure" - "--serverstransport.insecureskipverify=true" EOF helm -n traefik install -f /tmp/values.yaml traefik traefik/traefik
上述命令將於traefik命名空間中安裝以下對象,而端口經過hostNetwork映射到集羣外部,其中9000爲dashboard端口,8000爲http端口,8443爲https端口。
$ kubectl get pod,svc,ingressroute,deployment -n traefik NAME READY STATUS RESTARTS AGE pod/traefik-7474bbc877-m9c52 1/1 Running 0 2m35s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) ... service/traefik ClusterIP 10.111.109.186 <none> 9000/TCP,80/TCP,443/TCP NAME AGE ingressroute.traefik.containo.us/traefik-dashboard 2m35s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/traefik 1/1 1 1 2m35s
經過主機的9000端口咱們打開dashboard控制檯,其是一個很簡潔的控制檯,可用於查看一些狀態信息。
如今,咱們爲在default命名空間中部署的nginx建立一個ingress對象,咱們經過註釋kubernetes.io/ingress.class指定由traefik解析。
kubectl -n default apply -f - <<EOF apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: nginx annotations: kubernetes.io/ingress.class: traefik spec: rules: - host: nginx.app.zyl.io http: paths: - path: / backend: serviceName: nginx servicePort: 80 EOF
此處咱們設置ingress主機名稱爲nginx.app.zyl.io,那麼咱們在主機/etc/hosts爲其配置一個dns條目指向主機ip地址。
$ cat >> /etc/hosts <<EOF 192.168.110.6 nginx.app.zyl.io EOF $ curl nginx.app.zyl.io:8000 ... <title>Welcome to nginx!</title> ... $ curl 192.168.110.6:8000 404 page not found
kubectl
每次切換命名空間均需附帶-n <namespace>
參數,對於使用慣了oc
命令的用戶來講,這樣實在是太不方便了,幸虧有牛人開發了一個ahmetb/kubectx工具,咱們可用此來快速切換集羣上下文與命名空間。
安裝方法有兩種,方法一:經過kubectl插件包管理工具krew安裝;方法二:手動安裝。
# 安裝git yum -y install git # 安裝krew ( set -x; cd "$(mktemp -d)" && curl -fsSLO "https://github.com/kubernetes-sigs/krew/releases/latest/download/krew.{tar.gz,yaml}" && tar zxvf krew.tar.gz && KREW=./krew-"$(uname | tr '[:upper:]' '[:lower:]')_amd64" && "$KREW" install --manifest=krew.yaml --archive=krew.tar.gz && "$KREW" update ) # 配置環境變量: cat > .bashrc <<'EOF' export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH" EOF
然後咱們執行kubectl krew search
驗證krew是否運行,並檢查有哪些plugin可安裝,以下所示:
$ kubectl krew search NAME DESCRIPTION INSTALLED access-matrix Show an RBAC access matrix for server resources no advise-psp Suggests PodSecurityPolicies for cluster. no apparmor-manager Manage AppArmor profiles for cluster. no ...
接着,咱們執行以下命令安裝ctx(切換context上下文)與ns(切換命名空間):
kubectl krew install ctx kubectl krew install ns
安裝完成後,咱們則能夠插件方式運行kubectl
了,以下所示,咱們使用ns快速切換命名空間。
$ kubectl ns # 有哪些namespace default kube-node-lease kube-public kube-system traefik $ kubectl ns traefik # 切換到traefik命名空間 Context "kubernetes-admin@kubernetes" modified. Active namespace is "traefik". $ kubectl get pod # 此時已位於traefik命名空間 NAME READY STATUS RESTARTS AGE nginx-f89759699-254tt 1/1 Running 0 130m $ kubectl ns - # 切換回原命名空間
git clone https://github.com/ahmetb/kubectx.git ~/.kubectx COMPDIR=$(pkg-config --variable=completionsdir bash-completion) ln -sf ~/.kubectx/completion/kubens.bash $COMPDIR/kubens ln -sf ~/.kubectx/completion/kubectx.bash $COMPDIR/kubectx cat << FOE >> ~/.bashrc #kubectx and kubens export PATH=~/.kubectx:\$PATH FOE
若是咱們結合fzf則能夠交互模式運行上述命令,執行以下命令安裝fzf。
# 安裝fzf git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf ~/.fzf/install
不少場景,咱們的應用須要持久化數據,爲了簡單考慮,咱們選擇使用nfs-server-provisioner搭建一個持久化的NFS存儲系統,此存儲系統通常無法用於生產,但對於咱們測試來講足夠了。
首先,咱們須要安裝helm v3然後執行以下命令添加helm倉庫。
$ helm repo add stable https://kubernetes-charts.storage.googleapis.com "stable" has been added to your repositories
對於做者的單節點K8S集羣,咱們需執行以下命令確保以下標籤(labels)值,咱們將用其設置部署應用的節點選擇器(nodeSelector)。
% kubectl get node --show-labels NAME STATUS ROLES AGE VERSION LABELS cts.zyl.io Ready master 43h v1.18.3 kubernetes.io/hostname=cts.zyl.io,...
準備一個/app/nfs/0目錄供本節搭建的nfs服務所用,如做者準備的目錄大小僅10G左右。
mkdir -p /app/nfs/0
建立以下文件,其中,咱們指定將pod調度到cts.zyl.io主機,指定pod副本數爲1,爲保證nfs提供的存儲卷是持久化的,咱們需爲nfs server啓用持久化卷(persistence.enabled:true),雖然上面準備的目錄才10G大小,但此處仍可設置超過10G的大小(200Gi),指定建立的存儲卷爲默認存儲卷(storageClass.defaultClass:true),這樣若pvc未明確指定storageClass將使用此存儲類。
cat > /tmp/values.yaml <<'EOF' replicaCount: 1 persistence: enabled: true storageClass: "-" size: 200Gi storageClass: defaultClass: true nodeSelector: kubernetes.io/hostname: cts.zyl.io EOF
執行以下命令將nfs server部署到一個獨立的命名空間nfs-server-provisioner中:
kubectl create namespace nfs-server-provisioner helm -n nfs-server-provisioner install \ -f /tmp/values.yaml nfs-server-provisioner stable/nfs-server-provisioner
以下所示,部署清單中所需的持久化卷聲明(pvc)此時處於Pending狀態,此時咱們爲主機的/app/nfs/0建立一個持久化卷(pv),然後關聯到此pvc上。
$ oc get pvc NAME STATUS VOLUME CAPACITY ... data-nfs-server-provisioner-0 Pending $ kubectl -n nfs-server-provisioner create -f - <<EOF apiVersion: v1 kind: PersistentVolume metadata: name: data-nfs-server-provisioner-0 spec: capacity: storage: 200Gi accessModes: - ReadWriteOnce hostPath: path: /app/nfs/0 claimRef: kind: PersistentVolumeClaim name: data-nfs-server-provisioner-0 EOF
待pod啓動完成後,咱們可發現集羣上建立了一名爲nfs的默認存儲類,主機目錄/app/data/0存在一些文件。
$ oc get pod NAME READY STATUS RESTARTS AGE nfs-server-provisioner-0 1/1 Running 0 3s $ oc get storageclass NAME PROVISIONER RECLAIMPOLICY ... nfs (default) cluster.local/nfs-server-provisioner Delete ... $ ls /app/nfs/0/ ganesha.log nfs-provisioner.identity v4old v4recov vfs.conf
最後,讓咱們建立一pvc來驗證經過此存儲能爲咱們自動建立持久化卷pv,換句話說,此存儲類是自動提供的,咱們僅聲明須要多大的存儲,而底層存儲卷由存儲系統爲咱們自動建立好。
$ kubectl -n default create -f - <<EOF apiVersion: v1 kind: PersistentVolumeClaim metadata: name: test-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi EOF $ kubectl -n default get pvc NAME STATUS VOLUME CAPACITY ... test-pvc Bound pvc-ae8f8a8b-9700-494f-ad9f-259345918ec4 10Gi ... $ kubectl get pv NAME CAPACITY ACCESS ... STORAGECLASS pvc-ae8f8a8b-... 10Gi RWO ... nfs
接着,咱們執行kubectl -n default delete pvc test-pvc
,然後再去觀察pv可發現其被自動釋放了。
本節安裝k8s原生dashboard,這裏使用helm安裝,安裝方法見這裏,首先咱們添加helm倉庫:
helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/ helm repo add stable https://kubernetes-charts.storage.googleapis.com
參考Kubernetes monitoring architecture,若要在控制檯上顯示Pod的Cpu與Memory信息,則咱們須安裝Metrics Server5,但若咱們選擇使用coreos/kube-prometheus監控集羣,則可禁用metrics-server,因其已包含了metrics-server的功能。
The kube-prometheus stack includes a resource metrics API server, so the metrics-server addon is not necessary. Ensure the metrics-server addon is disabled on minikube:
這裏咱們選擇部署metrics-server,其僅收集集羣核心數據,如資源使用狀況,其功能雖沒有coreos/kube-prometheus全,但收集的數據不但可供dashbord用於呈現資源狀態,也可用於基於CPU與內存的應用水平擴展HPA與應用垂直擴展VPA。
以下所示,在安裝dashboard前,咱們先行將metrics-server安裝到獨立的kube-monitoring命名空間中,因咱們的ca證書是自簽名的,故須要使用--kubelet-insecure-tls
啓動metrics-server。
kubectl create namespace kube-monitoring cat > /tmp/values.yaml <<EOF args: - --kubelet-insecure-tls EOF helm -n kube-monitoring -f /tmp/values.yaml \ install metrics-server stable/metrics-server
等待pod啓動成功後,執行以下命令驗證檢查是否可獲取數據。
$ kubectl get --raw "/apis/metrics.k8s.io/v1beta1/nodes" $ kubectl top node NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% cts.zyl.io 273m 6% 1518Mi 41% $ kubectl top pod NAME CPU(cores) MEMORY(bytes) metrics-server-5b6896f6d7-snnbv 3m 13Mi
開始安裝dashboard,這裏咱們啓用metricsScraper,這樣將從metrics-server處獲取性能數據以呈現到控制檯上,而配置ingress使用https實在有點麻煩,爲了方便起見這裏使用NodePort將端口映射到集羣外。
kubectl create namespace kube-dashboard helm -n kube-dashboard install dash \ --set metricsScraper.enabled=true \ --set service.type=NodePort \ kubernetes-dashboard/kubernetes-dashboard
以下所示NodePort模式所分配的主機端口爲30808,故咱們可經過https://192.168.110.6:30808訪問控制檯。
$ oc get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) dash-kubernetes-dashboard NodePort 10.108.149.116 <none> 443:30808/TCP
以下所示,兩種登錄控制檯的方法,咱們採用Token方式登錄控制檯,獲取Token的步驟參考官方文檔Creating sample user按其步驟實施便可,本文再也不重複描述此過程。
以下所示,這是一個登錄成功後的概況圖: