還不會K8S嗎?先從kubeadm開始吧
kubeadm是Kubernetes官方提供的用於快速安裝Kubernetes集群的工具,伴隨Kubernetes每個版本的發佈都會同步更新,kubeadm會對集群配置方面的一些實踐做調整,通過實驗kubeadm可以學習到Kubernetes官方在集群配置上一些新的最佳實踐。
在Kubernetes的文檔Creating a single master cluster with kubeadm中已經給出了目前kubeadm的主要特性已經處於beta狀態了,在2018年將進入GA狀態,說明kubeadm離可以在生產環境中使用的距離越來越近了。
下面我將介紹一下kubeadm的安裝,比起k8s的二進制安裝方式,kubeadm的安裝門檻較低,更容易上手。
1. 準備工作
1.1 機器準備
準備三台Centos7.x虛擬機,具體配置如下:
IP | Role | CPU | Memory | Hostname |
---|---|---|---|---|
192.168.199.231 | master | >= 2C | >= 2G | master |
192.168.199.232 | worker | >= 2C | >= 2G | node1 |
192.168.199.233 | worker | >= 2C | >= 2G | node1 |
IP 根據你自己宿主機機器網段決定。
1.2 系統配置
1.2.1 主機名及域名解析
# 192.168.199.231上執行
hostnamectl set-hostname master
# 192.168.199.232上執行
hostnamectl set-hostname node1
# 192.168.199.233上執行
hostnamectl set-hostname node2
# 192.168.199.231、192.168.199.232、192.168.199.233三台都執行
cat <<EOF>>/etc/hosts
192.168.199.231 master
192.168.199.232 node1
192.168.199.233 node2
EOF
設置完後,相互ping一下看看網絡是否通。如:ping node1
1.2.2 免密登錄
設置 master 可以無密碼登錄所有節點的 root 賬戶:
## 第一步:在master節點執行,一路回車到底
ssh-keygen -t rsa
## 第二步:在master節點執行以下三句,然後分別輸入對應機器登錄密碼
ssh-copy-id root@master
ssh-copy-id root@node1
ssh-copy-id root@node2
1.2.3 配置yum源
注意:所有虛擬機都需要執行下面的操作
配置阿里軟件源(base和epel):
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo_bak
wget -O /etc/yum.repos.d/CentOS-Base.repo //mirrors.aliyun.com/repo/Centos-7.repo
mv /etc/yum.repos.d/epel.repo /etc/yum.repos.d/epel.repo.backup
mv /etc/yum.repos.d/epel-testing.repo /etc/yum.repos.d/epel-testing.repo.backup
wget -O /etc/yum.repos.d/epel.repo //mirrors.aliyun.com/repo/epel-7.repo
最後一句記得回車,配置完過後,可通過命令:
yum repolist
來查看是否配置成功。如果出現如下信息則表示成功:
- base: mirrors.aliyun.com
- extras: mirrors.aliyun.com
- updates: mirrors.aliyun.com
配置國內Kubernetes源:
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=//mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=//mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg //mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
配置docker源:
wget //mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
執行清理和更新:
yum clean all && yum makecache && yum update -y # 第一次需要比較久的時間,去喝杯水休息休息
1.2.4 安裝必要依賴包
在三台機器上執行命令:
yum install -y epel-release
yum install -y conntrack ntpdate ntp ipvsadm ipset jq iptables curl sysstat libseccomp wget
/usr/sbin/modprobe ip_vs # 這一句記得回車
ipvs 依賴 ipset
ntp 保證各機器系統時間同步;
1.2.5 關閉防火牆、SELinux、Swap分區
注意:所有虛擬機都需要執行下面的操作
關閉防火牆:
systemctl stop firewalld &&
systemctl disable firewalld &&
iptables -F && iptables -X && iptables -F -t nat && iptables -X -t nat &&
iptables -P FORWARD ACCEPT
關閉SELinux:
setenforce 0
sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
關閉Swap分區:
swapoff -a
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
1.2.6 配置內核參數
注意:所有虛擬機都需要執行下面的操作
將橋接的IPv4流量傳遞到iptables的鏈,swappiness參數調整:
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward=1
net.ipv4.tcp_tw_recycle=0
vm.swappiness=0 # 禁止使用 swap 空間,只有當系統 OOM 時才允許使用它
vm.overcommit_memory=1 # 不檢查物理內存是否夠用
vm.panic_on_oom=0 # 開啟 OOM
EOF
modprobe ip_vs_rr
modprobe br_netfilter
sysctl --system # 記得回車
2. 安裝Docker
2.1 安裝
Kubernetes從1.6開始使用CRI(Container Runtime Interface)容器運行時接口。默認的容器運行時仍然是Docker,使用的是kubelet中內置dockershim CRI實現。
查看版本:
# 查看docker版本
yum list docker-ce.x86_64 --showduplicates | sort -r
# 查看docker cli版本
yum list docker-ce-cli.x86_64 --showduplicates |sort -r
Kubernetes 1.15已經針對Docker的1.13.1, 17.03, 17.06, 17.09, 18.06,18.09等版本做了驗證,需要注意Kubernetes 1.15最低支持的Docker版本是1.13.1。 我們這裡在各節點安裝docker的19.03.9版本。
# 安裝docker、docker-cli
yum install -y docker-ce-19.03.9-3.el7 docker-ce-cli-19.03.9-3.el7
# 開機啟動 && 啟動docker
systemctl enable docker && systemctl start docker
# 查看版本
docker --version
安裝docker還可以通過腳本,詳情見://leisure.wang/procedural-framework/docker/112.html
2.2 配置鏡像加速
# 第一步:創建目錄(不存在則創建)
mkdir -p /etc/docker
# 第二步:創建並配置daemon.json文件
cat > /etc/docker/daemon.json <<EOF
{
"registry-mirrors": [
"//registry.docker-cn.com",
"//hub-mirror.c.163.com",
"//docker.mirrors.ustc.edu.cn"
],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "5"
}
}
EOF
# 第三步:重新加載配置並重啟docker
systemctl daemon-reload && systemctl restart docker
確認一下iptables filter表中FOWARD鏈的默認策略(pllicy)為ACCEPT:
# 命令
iptables -nvL
# 結果部分如下:
Chain INPUT (policy ACCEPT 321 packets, 18442 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 DOCKER-USER all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 DOCKER-ISOLATION-STAGE-1 all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all -- * docker0 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
0 0 DOCKER all -- * docker0 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all -- docker0 !docker0 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all -- docker0 docker0 0.0.0.0/0 0.0.0.0/0
3. 使用kubeadm部署k8s集群
3.1 安裝kubeadm、kubelet、kubectl
需要在每台機器上都安裝以下的軟件包:
- Kubelet:負責與其他節點集群通信,並進行本節點Pod和容器生命周期的管理。
- Kubeadm:是Kubernetes的自動化部署工具,降低了部署難度,提高效率。
- Kubectl:是Kubernetes集群管理工具。
查看可用版本:
yum list --showduplicates | grep 'kubeadm\|kubectl\|kubelet'
選擇安裝kubeadm1.18.0、kubelet1.18.0、kubectl1.18.0
# 安裝
yum install -y kubelet-1.18.0 kubeadm-1.18.0 kubectl-1.18.0 --disableexcludes=kubernetes
# 此時還不能啟動kubelet,先設置開機啟動
systemctl enable --now kubelet
從安裝結果可以看出還安裝了cri-tools, kubernetes-cni, socat三個依賴:
- socat是kubelet的依賴
- cri-tools是CRI(Container Runtime Interface)容器運行時接口的命令行工具
運行kubelet –help可以看到原來kubelet的絕大多數命令行flag參數都被DEPRECATED了。
而官方推薦我們使用–config指定配置文件,並在配置文件中指定原來這些flag所配置的內容。具體內容可以查看這裡Set Kubelet parameters via a config file。這也是Kubernetes為了支持動態Kubelet配置(Dynamic Kubelet Configuration)才這麼做的,參考Reconfigure a Node』s Kubelet in a Live Cluster。
kubelet的配置文件必須是json或yaml格式,具體可查看這裡。
3.2 配置kubeadm
查看kubelet安裝了哪些文件:
# 命令
rpm -ql kubelet
# 結果
/etc/kubernetes/manifests # 清單目錄
/etc/sysconfig/kubelet # 配置文件
/usr/bin/kubelet # 主程序
/usr/lib/systemd/system/kubelet.service # unit file
在所有虛擬機上修改/etc/sysconfig/kubelet,加入:
# 命令
sed -i "s/KUBELET_EXTRA_ARGS=/KUBELET_EXTRA_ARGS=\"--fail-swap-on=false\"/" /etc/sysconfig/kubelet
# 查看是否修改
cat /etc/sysconfig/kubelet
# 查看結果
KUBELET_EXTRA_ARGS="--fail-swap-on=false"
安裝 kubernetes 主要是安裝它的各個鏡像,而 kubeadm 已經為我們集成好了運行 kubernetes 所需的基本鏡像。但由於國內的網絡原因,在搭建環境時,無法拉取到這些鏡像。此時我們只需要修改為阿里雲提供的鏡像服務即可解決該問題。
導出配置文件(未修改文件,不可用):
kubeadm config print init-defaults --kubeconfig ClusterConfiguration > kubeadm.yml
針對kubeadm.yml文件做修改,新增修改處有4個,如下注釋位置,做相應修改即可:
apiVersion: kubeadm.k8s.io/v1beta2
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 192.168.199.231 # 修改項,更改為master節點IP
bindPort: 6443
nodeRegistration:
criSocket: /var/run/dockershim.sock
name: master
taints:
- effect: NoSchedule
key: node-role.kubernetes.io/master
---
apiServer:
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controlPlaneEndpoint: "" # 新增項
controllerManager: {}
dns:
type: CoreDNS
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers # 修改項,修改為阿里雲鏡像倉庫
kind: ClusterConfiguration
kubernetesVersion: v1.18.0
networking:
dnsDomain: cluster.local
podSubnet: "10.244.0.0/16" # 新增項,配置Flannel的默認網段
serviceSubnet: 10.96.0.0/12
scheduler: {}
---
# 新增項start:開啟IPVS模式
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
featureGates:
SupportIPVSProxyMode: true
mode: ipvs
# 新增項end:開啟IPVS模式
配置修改好後,將配置文件複製到node1、node2備用:
scp kubeadm.yml root@node1:/root
scp kubeadm.yml root@node2:/root
查看和拉取鏡像:
# 查看所需鏡像列表
kubeadm config images list --config kubeadm.yml
# 拉取鏡像 (所有機器都執行)
kubeadm config images pull --config kubeadm.yml
# 執行完畢後,通過命令就可以看到鏡像了:
docker images
3.3 使用kubeadm 配置master 節點
注意:在master執行下面的操作
3.3.1 安裝 kubernetes 主節點
執行以下命令初始化主節點,該命令指定了初始化時需要使用的配置文件,其中添加 –experimental-upload-certs 參數可以在後續執行加入節點時自動分發證書文件。追加的 tee kubeadm-init.log 用以輸出日誌。
# 初始化命令
kubeadm init --config=kubeadm.yml --upload-certs | tee kubeadm-init.log
# 成功則返回如下信息:
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:
//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.199.231:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:d65d8f7646c8503c40d622e29ff4ec74ce3aac5b83f87d2950d2301d6a1faf5c
node1、node2想要加入集群,需要執行上一步返回結果中的命令:
kubeadm join 192.168.199.231:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:d65d8f7646c8503c40d622e29ff4ec74ce3aac5b83f87d2950d2301d6a1faf5c
–token:加入集群的token
–discovery-token-ca-cert-hash:發現token證書hash
此時還無法通過命令kubectl get nodes查看節點信息,需要等下面的配置。
如果忘記了加入集群的命令怎麼辦呢?通過下面兩個方法獲取token和discovery-token-ca-cert-hash,然後按照上面的命令的格式拼接起來即可。
獲取Token,可以在 Master 上輸入以下命令查看:
kubeadm token list
默認情況下 Token 過期是時間是24小時,如果 Token 過期以後,可以輸入以下命令,生成新的 Token:
kubeadm token create
獲取discovery-token-ca-cert-hash 的方法,在 Master 運行以下命令查看:
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
注意:如果安裝 kubernetes 版本和下載的鏡像版本不統一則會出現 timed out waiting for the condition 錯誤。中途失敗或是想修改配置可以使用 kubeadm reset 命令重置配置,再做初始化操作即可。
3.3.2 配置 kubectl
執行初始化集群時候輸出結果中的命令:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
# 非root用戶執行
sudo chown $(id -u):$(id -g) $HOME/.kube/config
驗證是否成功:
# 命令
kubectl get nodes
# 結果
NAME STATUS ROLES AGE VERSION
master NotReady master 18m v1.18.0
node1 NotReady <none> 14m v1.18.0
node2 NotReady <none> 14m v1.18.0
至此主機誒單配置完成。
3.3.3 kubeadm init執行過程
- init:指定版本進行初始化操作
- preflight:初始化前的檢查和下載所需要的 Docker 鏡像文件
- kubelet-start:生成 kubelet 的配置文件 var/lib/kubelet/config.yaml,沒有這個文件 kubelet 無法啟動,所以初始化之前的 kubelet 實際上啟動不會成功
- certificates:生成 Kubernetes 使用的證書,存放在 /etc/kubernetes/pki 目錄中
- kubeconfig:生成 KubeConfig 文件,存放在 /etc/kubernetes 目錄中,組件之間通信需要使用對應文件
- control-plane:使用 /etc/kubernetes/manifest 目錄下的 YAML 文件,安裝 Master 組件
- etcd:使用 /etc/kubernetes/manifest/etcd.yaml 安裝 Etcd 服務
- wait-control-plane:等待 control-plan 部署的 Master 組件啟動
- apiclient:檢查 Master 組件服務狀態。
- uploadconfig:更新配置
- kubelet:使用 configMap 配置 kubelet
- patchnode:更新 CNI 信息到 Node 上,通過注釋的方式記錄
- mark-control-plane:為當前節點打標籤,打了角色 Master,和不可調度標籤,這樣默認就不會使用 Master 節點來運行 Pod
- bootstrap-token:生成 token 記錄下來,後邊使用 kubeadm join 往集群中添加節點時會用到
- addons:安裝附加組件 CoreDNS 和 kube-proxy
3.4 使用kubeadm配置 worker 節點
3.4.1 將worker加入到集群
將 worker節點加入到集群中很簡單,上一步也做了介紹,只需要執行init返回結果中的命令:
kubeadm join 192.168.199.231:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:d65d8f7646c8503c40d622e29ff4ec74ce3aac5b83f87d2950d2301d6a1faf5c
3.4.2 驗證是否成功
在master節點上運行:
# 命令
kubectl get cs,nodes
# 結果
NAME STATUS MESSAGE ERROR
componentstatus/scheduler Healthy ok
componentstatus/controller-manager Healthy ok
componentstatus/etcd-0 Healthy {"health":"true"}
NAME STATUS ROLES AGE VERSION
node/master NotReady master 84m v1.18.0
node/node1 NotReady <none> 80m v1.18.0
node/node2 NotReady <none> 79m v1.18.0
如果 worker節點加入 master 時配置有問題可以在 worker節點上使用 kubeadm reset 重置配置再使用 kubeadm join 命令重新加入即可。希望在 master 節點刪除 node ,可以使用 kubeadm delete nodes
3.4.3 查看 pod 狀態
# 在master上運行
kubectl get pod -n kube-system -o wide
# 結果
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
coredns-7ff77c879f-k94rw 0/1 Pending 0 86m <none> <none> <none> <none>
coredns-7ff77c879f-whhdf 0/1 Pending 0 86m <none> <none> <none> <none>
etcd-master 1/1 Running 0 86m 192.168.199.231 master <none> <none>
kube-apiserver-master 1/1 Running 0 86m 192.168.199.231 master <none> <none>
kube-controller-manager-master 1/1 Running 0 86m 192.168.199.231 master <none> <none>
kube-proxy-8jvj5 1/1 Running 1 86m 192.168.199.231 master <none> <none>
kube-proxy-hm8cx 1/1 Running 1 82m 192.168.199.232 node1 <none> <none>
kube-proxy-psnc9 1/1 Running 1 82m 192.168.199.233 node2 <none> <none>
kube-scheduler-master 1/1 Running 0 86m 192.168.199.231 master <none> <none>
由此可以看出 coredns 尚未運行,此時我們還需要安裝網絡插件。
3.5 配置網絡
Kubernetes 中可選的 CNI 插件如下:
- Flannel
- Calico
- Canal
- Weave
3.5.1 安裝flannel網絡
# 下載kube-flannel.yml文件,如果無法下載請在附件中獲取。
curl -O //raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
# 安裝
kubectl apply -f kube-flannel.yml
3.5.2 配置網卡名稱(可選)
如果Node有多個網卡的話,參考flannel issues 39701,目前需要在kube-flannel.yml中使用–iface參數指定集群主機內網網卡的名稱,否則可能會出現dns無法解析。需要將kube-flannel.yml下載到本地,flanneld啟動參數加上–iface=
# 部分內容
......
containers:
- name: kube-flannel
image: quay.io/coreos/flannel:v0.11.0-amd64
command:
- /opt/bin/flanneld
args:
- --ip-masq
- --kube-subnet-mgr
- --iface=ens32
......
3.5.3 查看Pod狀態
使用kubectl get pod –all-namespaces -o wide確保所有的Pod都處於Running狀態:
# 命令
watch kubectl get pod --all-namespaces -o wide
# 結果(需要等待所有狀態為Running,時間可能需要3-5分鐘)
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-system coredns-7ff77c879f-k94rw 1/1 Running 0 126m 10.244.0.3 master <none> <none>
kube-system coredns-7ff77c879f-whhdf 1/1 Running 0 126m 10.244.0.2 master <none> <none>
kube-system etcd-master 1/1 Running 0 126m 192.168.199.231 master <none> <none>
kube-system kube-apiserver-master 1/1 Running 0 126m 192.168.199.231 master <none> <none>
kube-system kube-controller-manager-master 1/1 Running 0 126m 192.168.199.231 master <none> <none>
kube-system kube-flannel-ds-amd64-6rcjk 1/1 Running 0 15m 192.168.199.231 master <none> <none>
kube-system kube-flannel-ds-amd64-n464m 1/1 Running 0 15m 192.168.199.232 node1 <none> <none>
kube-system kube-flannel-ds-amd64-rlghv 1/1 Running 0 15m 192.168.199.233 node2 <none> <none>
kube-system kube-proxy-8jvj5 1/1 Running 1 126m 192.168.199.231 master <none> <none>
kube-system kube-proxy-hm8cx 1/1 Running 1 122m 192.168.199.232 node1 <none> <none>
kube-system kube-proxy-psnc9 1/1 Running 1 121m 192.168.199.233 node2 <none> <none>
kube-system kube-scheduler-master 1/1 Running 0 126m 192.168.199.231 master <none> <none>
至此基本環節已經部署完畢,如果沒有問題,就可以展開k8s的學習之旅了。
3.5.4 問題處理(可選)
3.5.4.1 解決 ImagePullBackOff
在使用 watch kubectl get pods –all-namespaces 命令觀察 Pods 狀態時如果出現 ImagePullBackOff 無法 Running 的情況,請嘗試使用如下步驟處理:
- Master 中刪除 Nodes:kubectl delete nodes
- worker中重置配置:kubeadm reset
- worker重啟計算機:reboot
- worker重新加入集群:kubeadm join
3.5.4.2 Master節點參與工作負載
出於安全原因,您的群集不會在主服務器上安排pod。如果您希望能夠在主服務器上安排pod,例如對於用於開發的單機Kubernetes集群,可以運行以下命令:
# 所有主服務器都安排 pod
kubectl taint nodes --all node-role.kubernetes.io/master-
# 指定節點 master 服務器都安排 pod
kubectl taint nodes <master-hostname> node-role.kubernetes.io/master-
如:kubectl taint nodes master node-role.kubernetes.io/master-
3.6 驗證集群DNS是否可用
3.6.1 新建文件my-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
app: my-nginx
replicas: 2
template:
metadata:
labels:
app: my-nginx
spec:
containers:
- name: my-nginx
image: nginx:1.7.9
ports:
- containerPort: 80
3.6.2 創建Deployment並生成my-nginx服務
# 創建Deployment
kubectl create -f my-nginx.yaml
# 查看Deployment
kubectl get deploy
# 生成服務
kubectl expose deploy my-nginx
# 查看服務
kubectl get services(或 kubectl get svc)
# 結果
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3h2m
my-nginx ClusterIP 10.110.206.225 <none> 80/TCP 7m34s
3.6.3 創建dnsutils-ds.yml文件
創建另一個 Pod,查看 /etc/resolv.conf 是否包含 kubelet 配置的 –cluster-dns 和 –cluster-domain,是否能夠將服務 my-nginx 解析到對應的 Cluster IP 10.110.206.225上
apiVersion: v1
kind: Service
metadata:
name: dnsutils-ds
labels:
app: dnsutils-ds
spec:
type: NodePort
selector:
app: dnsutils-ds
ports:
- name: http
port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: dnsutils-ds
labels:
addonmanager.kubernetes.io/mode: Reconcile
spec:
selector:
matchLabels:
app: dnsutils-ds
template:
metadata:
labels:
app: dnsutils-ds
spec:
containers:
- name: my-dnsutils
image: tutum/dnsutils:latest
command:
- sleep
- "3600"
ports:
- containerPort: 80
3.6.4 創建pod dnsutils-ds
kubectl create -f dnsutils-ds.yml
3.6.5 查看pod節點
# 命令
kubectl get pods
# 結果
NAME READY STATUS RESTARTS AGE
curl 0/1 CrashLoopBackOff 13 46m
dnsutils-ds-2xgtq 1/1 Running 0 103s
dnsutils-ds-dvzjm 1/1 Running 0 103s
dnsutils-ds-xtsvz 1/1 Running 0 103s
my-nginx-5c7d476867-sqpjv 1/1 Running 0 19m
my-nginx-5c7d476867-vv57z 1/1 Running 0 19m
3.6.6 開始驗證DNS
# 命令
kubectl exec dnsutils-ds-2xgtq -- nslookup my-nginx
# 結果
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: my-nginx.default.svc.cluster.local
Address: 10.110.206.225
從結果看Address: 10.110.206.225已經成功了。
另外,解析外部域名時,需要以 . 結尾:
# 命令
kubectl exec dnsutils-ds-2xgtq -- nslookup leisure.wang.
# 結果
Server: 10.96.0.10
Address: 10.96.0.10#53
Non-authoritative answer:
Name: leisure.wang
Address: 121.36.158.21
3.7 從集群中刪除Node
如果需要從集群中移除node2這個Node執行下面的命令:
在master節點上執行:
kubectl drain node2 --delete-local-data --force --ignore-daemonsets
kubectl delete node node2
在 Node 被刪除,需要重啟所有 kubeadm 安裝狀態:
kubeadm reset
# 如果要完全刪除,請執行下面的清理命令
ifconfig cni0 down
ip link delete cni0
ifconfig flannel.1 down
ip link delete flannel.1
rm -rf /var/lib/cni/
3.8 解決apiserver訪問時匿名用戶禁用問題
瀏覽器訪問 kube-apiserver 的安全端口 6443 時,提示:
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {
},
"status": "Failure",
"message": "forbidden: User \"system:anonymous\" cannot get path \"/\"",
"reason": "Forbidden",
"details": {
},
"code": 403
}
對於正式環境,需要創建一個用戶並授權,在上面二進制二進制安裝里介紹過,多少還是煩了點。
對於學習環境,我們不需要那麼麻煩,不就是匿名用戶被禁用了嗎,直接給匿名用戶授權就可以了。
解決辦法:綁定一個cluster-admin的權限
kubectl create clusterrolebinding system:anonymous --clusterrole=cluster-admin --user=system:anonymous
4. 部署whoami
whoami 是一個簡單的HTTP docker服務,用於打印容器ID
在 Master 運行部署 Whoami:
kubectl create deployment whoami --image=idoall/whoami
查看 Whoami 部署狀態:
kubectl get deployments
查看 Whoami 的部署信息:
kubectl describe deployment whoami
查看 Whoami 的pod信息:
kubectl describe pod whoami
為 Whoami 擴展端口;創建一個可以通過互聯網訪問的 Whoami 容器:
kubectl create service nodeport whoami --tcp=80:80
[本文由//leisure.wang/整理提供]
上面的命令將在主機上為 Whoami 部署創建面向公眾的服務。
由於這是一個節點端口部署,因此 kubernetes 會將此服務分配給32000+範圍內的主機上的端口。
查看當前的服務狀態:
# 命令
kubectl get svc,pods -o wide
# 結果
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/dnsutils-ds NodePort 10.97.94.13 <none> 80:30157/TCP 37m app=dnsutils-ds
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3h45m <none>
service/my-nginx ClusterIP 10.110.206.225 <none> 80/TCP 51m app=my-nginx
service/whoami NodePort 10.108.27.255 <none> 80:32729/TCP 29s app=whoami
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/curl 0/1 CrashLoopBackOff 20 82m 10.244.1.2 node1 <none> <none>
pod/dnsutils-ds-2xgtq 1/1 Running 0 37m 10.244.1.4 node1 <none> <none>
pod/dnsutils-ds-dvzjm 1/1 Running 0 37m 10.244.0.4 master <none> <none>
pod/dnsutils-ds-xtsvz 1/1 Running 0 37m 10.244.2.3 node2 <none> <none>
pod/my-nginx-5c7d476867-sqpjv 1/1 Running 0 55m 10.244.1.3 node1 <none> <none>
pod/my-nginx-5c7d476867-vv57z 1/1 Running 0 55m 10.244.2.2 node2 <none> <none>
pod/whoami-7976c8ddf6-9lbcp 1/1 Running 0 5m13s 10.244.2.4 node2 <none> <none>
上面的服務可以看到 Whoami 運行在 32729 端口。
測試 Whoami 服務是否運行正常:
# 命令
curl node1:32729
# 結果
[mshk.top]I'm whoami-7976c8ddf6-9lbcp
擴展部署應用:
kubectl scale --replicas=3 deployment/whoami
查看擴展後的結果,可以看到 Whoami 在 master、node1、node2上面都有部署
ClusterIP 模式會提供一個集群內部的虛擬IP(與Pod不在同一網段),以供集群內部的 Pod 之間通信使用。
刪除 Whoami 部署:
kubectl delete deployment whoami
kubectl delete service whoami
5. 部署Dashboard
Kubernetes Dashboard 是 Kubernetes 集群的 Web UI,用於管理集群。
5.1 安裝
註:在master節點上進行如下操作
5.1.0 下載配置文件
由於網絡原因,可能無法下載,無法下載則請直接使用5.1.1文件內容
wget //raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml
如果下載成功,請參照5.1.1做如下修改:
- 修改鏡像地址為阿里雲
- 修改類型為 NodePort 訪問(無type則新增)
- 設置端口號為 30001
5.1.1 創建文件kubernetes-dashboard.yaml
apiVersion: v1
kind: Secret
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-certs
namespace: kube-system
type: Opaque
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kube-system
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: kubernetes-dashboard-minimal
namespace: kube-system
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["create"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["create"]
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs"]
verbs: ["get", "update", "delete"]
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["kubernetes-dashboard-settings"]
verbs: ["get", "update"]
- apiGroups: [""]
resources: ["services"]
resourceNames: ["heapster"]
verbs: ["proxy"]
- apiGroups: [""]
resources: ["services/proxy"]
resourceNames: ["heapster", "http:heapster:", "https:heapster:"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kubernetes-dashboard-minimal
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kube-system
---
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kube-system
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
k8s-app: kubernetes-dashboard
template:
metadata:
labels:
k8s-app: kubernetes-dashboard
spec:
containers:
- name: kubernetes-dashboard
image: registry.aliyuncs.com/google_containers/kubernetes-dashboard-amd64:v1.10.1 # 修改鏡像地址為阿里雲
ports:
- containerPort: 8443
protocol: TCP
args:
- --auto-generate-certificates
volumeMounts:
- name: kubernetes-dashboard-certs
mountPath: /certs
- mountPath: /tmp
name: tmp-volume
livenessProbe:
httpGet:
scheme: HTTPS
path: /
port: 8443
initialDelaySeconds: 30
timeoutSeconds: 30
volumes:
- name: kubernetes-dashboard-certs
secret:
secretName: kubernetes-dashboard-certs
- name: tmp-volume
emptyDir: {}
serviceAccountName: kubernetes-dashboard
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
---
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kube-system
spec:
type: NodePort # 修改類型為 NodePort 訪問(無type則新增)
ports:
- port: 443
targetPort: 8443
nodePort: 30001 # 設置端口號為 30001
selector:
k8s-app: kubernetes-dashboard
5.1.2 部署
kubectl create -f kubernetes-dashboard.yaml
5.1.3 查看
kubectl -n kube-system get pods
kubectl -n kube-system get service kubernetes-dashboard
kubectl -n kube-system describe service kubernetes-dashboard
5.2 訪問
需要使用 NodeIP:30001(如://192.168.199.231:30001/) 訪問 Dashboard,因為證書原因除火狐瀏覽器外其它瀏覽器無法直接打開頁面。
作為學習,暫時可以不用在意這些細節。訪問後,在火狐里點擊高級>接受風險並繼續。
此時將會看到「Kubernetes 儀錶板」。
5.3 登錄
5.3.1 kubeconfig方式
該config文件位置一般是 ~/.kube/config(Master節點),只要將該文件下載到本地機器上,登錄的時候選擇它就行了。
5.3.2 令牌方式
創建訪問Dashboard的token,需要創建一個 Admin 用戶並授予 Admin 角色綁定,使用下面的 yaml文件 創建 admin 用戶並賦予管理員權限,然後可以通過 Token 訪問 kubernetes。
創建 kubernetes-dashboard-admin.yaml 文件:
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: kubernetes-dashboard
labels:
k8s-app: kubernetes-dashboard
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kube-system
執行部署:
kubectl apply -f kubernetes-dashboard-admin.yaml
獲取secret中的token值:
kubectl get secret -o wide --all-namespaces | grep kubernetes-dashboard-token
# 記得替換成你自己的secret資源名
kubectl -n kube-system describe secret kubernetes-dashboard-token-bsjtr
也可以通過 jsonpath 直接獲取 token:
kubectl -n kube-system get secret kubernetes-dashboard-token-bsjtr -o jsonpath={.data.token}|base64 -d
也可以使用下面的命令,直接獲取 kubernetes-dashboard-token 的值,然後直接打印輸出:
k8tokenvalue=`kubectl get secret -o wide --all-namespaces | grep kubernetes-dashboard-token | awk '{print $2}'`;kubectl -n kube-system get secret $k8tokenvalue -o jsonpath={.data.token}|base64 -d | awk '{print $1}'
注意:下面的獲取token值的方式和上面三種方式選擇一種即可。
您還可以通過kubectl create clusterrolebinding的方式來授予 Dashboard 服務 Admin 管理員權限:
kubectl create serviceaccount dashboard-admin -n kube-system
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')
登錄成功後就能看到後台頁面了:
6. Weave Scope 監控集群
創建 Kubernetes 集群並部署容器化應用只是第一步。一旦集群運行起來,我們需要確保一起正常,所有必要組件就位並各司其職,有足夠的資源滿足應用的需求。Kubernetes 是一個複雜系統,運維團隊需要有一套工具幫助他們獲知集群的實時狀態,並為故障排查提供及時和準確的數據支持。
6.1 安裝
Weave Scope 是 Docker 和 Kubernetes 可視化監控工具。Scope 提供了至上而下的集群基礎設施和應用的完整視圖,用戶可以輕鬆對分佈式的容器化應用進行實時監控和問題診斷。
在 K8s 集群中安裝 Scope 的方法很簡單,使用下面的命令:
# 命令
kubectl apply -f "//cloud.weave.works/k8s/scope.yaml?k8s-version=$(kubectl version | base64 | tr -d '\n')&k8s-service-type=NodePort"
# 結果
service-type=NodePort"
namespace/weave created
serviceaccount/weave-scope created
clusterrole.rbac.authorization.k8s.io/weave-scope created
clusterrolebinding.rbac.authorization.k8s.io/weave-scope created
deployment.apps/weave-scope-app created
service/weave-scope-app created
deployment.apps/weave-scope-cluster-agent created
daemonset.apps/weave-scope-agent created
部署成功後有如下組件:
# 命令
kubectl get pod -n weave
# 結果
NAME READY STATUS RESTARTS AGE
weave-scope-agent-2t7z2 0/1 ContainerCreating 0 60s
weave-scope-agent-ll9r9 0/1 ContainerCreating 0 60s
weave-scope-agent-qzp2b 0/1 ContainerCreating 0 60s
weave-scope-app-bc7444d59-lznk8 0/1 ContainerCreating 0 62s
weave-scope-cluster-agent-7944c858c9-ms7mz 0/1 ContainerCreating 0 61s
# 命令
kubectl get svc -n weave
# 結果
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
weave-scope-app NodePort 10.108.61.84 <none> 80:30286/TCP 3m9s
# 命令
kubectl get deploy -n weave
# 結果
NAME READY UP-TO-DATE AVAILABLE AGE
weave-scope-app 1/1 1 1 4m19s
weave-scope-cluster-agent 1/1 1 1 4m18s
- DaemonSet weave-scope-agent,集群每個節點上都會運行的 scope agent 程序,負責收集數據。
- Deployment weave-scope-app,scope 應用,從 agent 獲取數據,通過 Web UI 展示並與用戶交互。
- Service weave-scope-app,默認是 ClusterIP 類型,我們已經在上面的命令中添加了參數k8s-service-type=NodePort修改為 NodePort。
6.2 使用Scope
瀏覽器訪問//MASTER_IP:30286/(端口可在上一步查看命令中獲得),cope 默認顯示當前所有的 Controller(Deployment、DaemonSet 等)。
6.2.1 拓撲結構
Scope 會自動構建應用和集群的邏輯拓撲。比如點擊頂部 Pods,會顯示所有 Pod 以及 Pod 之間的依賴關係。
點擊 Hosts,會顯示各個節點之間的關係,可以在 Scope 中查看資源的 CPU 和內存使用情況。
6.2.2 在線操作
Scope 還提供了便捷的在線操作功能,比如選中某個 Host,點擊 >_ 按鈕可以直接在瀏覽器中打開節點的命令行終端:
點擊 Deployment 的 + 可以執行 Scale Up 操作:
可以查看 Pod 的日誌:
可以 attach、restart、stop 容器,以及直接在 Scope 中排查問題:
6.2.3 強大的搜索功能
Scope 支持關鍵字搜索和定位資源。
還可以進行條件搜索,比如查找和定位 MEMORY > 1M 的 Containers。
Weave Scope 界面極其友好,操作簡潔流暢,更多功能留給大家去探索。
官方文檔://www.weave.works/docs/scope/latest/installing/#k8s
寫在最後
通過kubeadm安裝k8s集群環境的介紹就到這裡了,書寫安裝過程難免出現不足的地方,如果出了問題,需要讀者多多思考。由於國內網絡的原因,文檔中所需要的大部分配置文件都已經貼了出來,讀者只需要根據自己的機器環境做相應的修改即可。通過kubeadm安裝k8s集群環境,相對於二進制的安裝方式來說,還是比較簡單的,需要多多實踐,才能出真知。我是東方雨傾,感謝大家的支持,謝謝!
附件
鏈接://pan.baidu.com/s/1qWdZ_CclTxm2ybE4h8dziA
提取碼:ruo5
原文地址://leisure.wang/procedural-framework/docker/513.html