使用kubeadm搭建一單節點k8s測試集羣

前言

本人以前的實驗環境一直用的是OCP/OKD集羣,其搭建在PC Server服務器上,現須要在本身的windows工做站上搭建一個K8S集羣,首先想到的是使用CodeReady Container(CRC)來搭建一個OKD集羣,但其資源要求實在是過高(4C9G內存),且CRC所需的虛擬化軟件hyper-vvirshbox有衝突,鑑於此問題,雖然有minikube可供選擇,但本人決定手動搭建一個原生態K8S集羣。node

本人實驗環境爲virshbox安裝的一臺虛擬機,其操做系統版本爲Centos Linux 8CPU 4個,內存4G,磁盤35G,其擁有兩塊網卡,網卡1鏈接到NAT網絡以便利用宿主機網絡鏈接英特網,而網卡2鏈接到Host-Only網絡,K8S API監聽在在此網絡上,主機名稱爲cts.zyl.iolinux

主機名 主機資源 網卡1 網卡2
cts.zyl.io 4C4G、Disk:35G Nat網絡,dhcp獲取ip Host-only網絡,靜態配置IP192.168.110.6

安裝容器運行時

參考k8s官方文檔cri-o官方文檔咱們先選擇一容器運行時,如做者對docker容器運行時實在不敢興趣1,故計劃安裝cri-o輕量級容器運行時,參考下圖,做者準備安裝k8s 1.18,故選擇cri-o 1.18.xnginx

image.png

對於Centos Linux 8操做系統,執行以下命令安裝CRI-O容器運行時2git

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的管理工具crictl3kubeadm會使用其拉取鏡像。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.iok8s.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(網橋)在容器間傳輸流量,亦或者如dockercrio4默認的網絡插件一樣基於網橋傳輸流量,此時需加載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

開始安裝kubeadm

上節已安裝了cri-o容器運行時,本節咱們將安裝kubeadm,但在此前,咱們參考官方文檔Installing kubeadm瞭解一些重要事項,並完善其餘所需步驟。api

  • 雖然對於本文搭建的單節點集羣來所此處沒任何意義,但爲了完整性考慮,我仍是記錄於此:檢查集羣各節點,其需具有獨立的主機名稱、MAC地址及product_uuidcat /sys/class/dmi/id/product_uuid);
  • 主機需配置防火牆放行一些端口,爲了簡單起見,關閉主機防火牆:
systemctl stop firewalld
systemctl disable firewalld
  • 禁用系統Swap,不然kubeadm會報錯。
cat > /etc/sysctl.d/99-disable-swap.conf <<EOL
vm.swappiness=0
EOL
sysctl --system

vi /etc/fstab      # 註釋swap行
  • 禁用selinux或設置爲permissive,不然kubeadm會報錯。
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config

接着,執行以下命令安裝kubeletkubeadmkubectl,然後設置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

注意

  • 因網絡問題,此處yum源咱們選擇阿里雲倉庫,而又因當前無EL8倉庫,故此處只能選擇EL7
  • 此時kubelete會不斷重啓,但這是正常行爲,其等待咱們運行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.

咱們配置的criocgroup驅動爲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

注意etcdkube-apiserverkube-controller-managerkube-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集羣,其當前僅含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

配置proxy使用ipvs模式

參考這裏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         
...

調整集羣CoreDNS配置

對於生產環境,K8S集羣節點主機名應可供DNS域名解析出來,不然可能會因主機名沒法被解析而形成某些應用異常,如metrics-server,一樣,對於建立的Ingress所分配的域名,也應被DNS域名系統正確解析,不然咱們不得不手動爲每一個Ingress配置的主機名修改/etc/hosts文件已作靜態配置。

對於本文搭建的測試環境,咱們不在單獨配置額外的DNS域名系統,而是調整K8S集羣的CoreDNS域名系統,以下所示。

參考Custom DNS Entries For Kubernetes文章,咱們調整configmap:coredns,於其中添加一個zyl.ioZonefile,而後於其中添加對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                   :::*

安裝附加組件(Add-on

爲了完善集羣功能,本章介紹一些基本的附加組件,咱們可按需配置,如dashboard對咱們測試來講沒啥用,而ingress、持久化存儲比較有用。

經過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映射到集羣外部,其中9000dashboard端口,8000http端口,8443https端口。

$ 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控制檯,其是一個很簡潔的控制檯,可用於查看一些狀態信息。

image.png

如今,咱們爲在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安裝;方法二:手動安裝。

  • 方法1:經過krew安裝插件方法,參考這裏咱們先安裝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持久化存儲系統

不少場景,咱們的應用須要持久化數據,爲了簡單考慮,咱們選擇使用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控制檯

本節安裝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,若要在控制檯上顯示PodCpuMemory信息,則咱們須安裝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按其步驟實施便可,本文再也不重複描述此過程。

image.png

以下所示,這是一個登錄成功後的概況圖:

image.png


  1. crio: ocp/okd默認容器運行時爲crio
  2. error: 本人安裝好k8s後,對於此倉庫後續更新遇到ERROR: The certificate of ‘download.opensuse.org’ is not trusted錯誤,估計系統ca有問題
  3. crictl: 此工具做用可用命令alias docker=crictl來表述
  4. crio:默認插件存儲於/etc/cni/net.d/100-crio-bridge.conf目錄
  5. metrics: 其是Heapster的輕量化版本,且Heapster早已被廢棄
相關文章
相關標籤/搜索