Kubernetes概述
簡介
Kubernetes是一個開源的,用於管理雲平臺中多個主機上的容器化的應用,Kubernetes的目標是讓部署容器化的應用簡單並且高效(powerful),Kubernetes提供了應用部署,規劃,更新,維護的一種機制。
Kubernetes一個核心的特點就是能夠自主的管理容器來保證雲平臺中的容器按照用戶的期望狀態運行着(比如用戶想讓apache一直運行,用戶不需要關心怎麼去做,Kubernetes會自動去監控,然後去重啓,新建,總之,讓apache一直提供服務),管理員可以加載一個微型服務,讓規劃器來找到合適的位置,同時,Kubernetes也系統提升工具以及人性化方面,讓用戶能夠方便的部署自己的應用(就像canary deployments)。
現在Kubernetes着重於不間斷的服務狀態(比如web服務器或者緩存服務器)和原生雲平臺應用(Nosql),在不久的將來會支持各種生產雲平臺中的各種服務,例如,分批,工作流,以及傳統數據庫。
在Kubenetes中,所有的容器均在Pod中運行,一個Pod可以承載一個或者多個相關的容器,在後邊的案例中,同一個Pod中的容器會部署在同一個物理機器上並且能夠共享資源。一個Pod也可以包含O個或者多個磁盤卷組(volumes),這些卷組將會以目錄的形式提供給一個容器,或者被所有Pod中的容器共享,對於用戶創建的每個Pod,系統會自動選擇那個健康並且有足夠容量的機器,然後創建類似容器的容器,當容器創建失敗的時候,容器會被node agent自動的重啓,這個node agent叫kubelet,但是,如果是Pod失敗或者機器,它不會自動的轉移並且啓動,除非用戶定義了 replication controller。
用戶可以自己創建並管理Pod,Kubernetes將這些操作簡化爲兩個操作:基於相同的Pod配置文件部署多個Pod複製品;創建可替代的Pod當一個Pod掛了或者機器掛了的時候。而Kubernetes API中負責來重新啓動,遷移等行爲的部分叫做“replication controller”,它根據一個模板生成了一個Pod,然後系統就根據用戶的需求創建了許多冗餘,這些冗餘的Pod組成了一個整個應用,或者服務,或者服務中的一層。一旦一個Pod被創建,系統就會不停的監控Pod的健康情況以及Pod所在主機的健康情況,如果這個Pod因爲軟件原因掛掉了或者所在的機器掛掉了,replication controller 會自動在一個健康的機器上創建一個一摸一樣的Pod,來維持原來的Pod冗餘狀態不變,一個應用的多個Pod可以共享一個機器。
我們經常需要選中一組Pod,例如,我們要限制一組Pod的某些操作,或者查詢某組Pod的狀態,作爲Kubernetes的基本機制,用戶可以給Kubernetes Api中的任何對象貼上一組 key:value的標籤,然後,我們就可以通過標籤來選擇一組相關的Kubernetes Api 對象,然後去執行一些特定的操作,每個資源額外擁有一組(很多) keys 和 values,然後外部的工具可以使用這些keys和vlues值進行對象的檢索,這些Map叫做annotations(註釋)。
Kubernetes支持一種特殊的網絡模型,Kubernetes創建了一個地址空間,並且不動態的分配端口,它可以允許用戶選擇任何想使用的端口,爲了實現這個功能,它爲每個Pod分配IP地址。
現代互聯網應用一般都會包含多層服務構成,比如web前臺空間與用來存儲鍵值對的內存服務器以及對應的存儲服務,爲了更好的服務於這樣的架構,Kubernetes提供了服務的抽象,並提供了固定的IP地址和DNS名稱,而這些與一系列Pod進行動態關聯,這些都通過之前提到的標籤進行關聯,所以我們可以關聯任何我們想關聯的Pod,當一個Pod中的容器訪問這個地址的時候,這個請求會被轉發到本地代理(kube proxy),每臺機器上均有一個本地代理,然後被轉發到相應的後端容器。Kubernetes通過一種輪訓機制選擇相應的後端容器,這些動態的Pod被替換的時候,Kube proxy時刻追蹤着,所以,服務的 IP地址(dns名稱),從來不變。
所有Kubernetes中的資源,比如Pod,都通過一個叫URI的東西來區分,這個URI有一個UID,URI的重要組成部分是:對象的類型(比如pod),對象的名字,對象的命名空間,對於特殊的對象類型,在同一個命名空間內,所有的名字都是不同的,在對象只提供名稱,不提供命名空間的情況下,這種情況是假定是默認的命名空間。UID是時間和空間上的唯一。
起源
大規模容器集羣管理工具,從Borg到Kubernetes
在Docker 作爲高級容器引擎快速發展的同時,Google也開始將自身在容器技術及集羣方面的積累貢獻出來。在Google內部,容器技術已經應用了很多年,Borg系統運行管理着成千上萬的容器應用,在它的支持下,無論是谷歌搜索、Gmail還是谷歌地圖,可以輕而易舉地從龐大的數據中心中獲取技術資源來支撐服務運行。
Borg是集羣的管理器,在它的系統中,運行着衆多集羣,而每個集羣可由成千上萬的服務器聯接組成,Borg每時每刻都在處理來自衆多應用程序所提交的成百上千的Job, 對這些Job進行接收、調度、啓動、停止、重啓和監控。正如Borg論文中所說,Borg提供了3大好處:
1)隱藏資源管理和錯誤處理,用戶僅需要關注應用的開發。
2) 服務高可用、高可靠。
3) 可將負載運行在由成千上萬的機器聯合而成的集羣中。
作爲Google的競爭技術優勢,Borg理所當然的被視爲商業祕密隱藏起來,但當Tiwtter的工程師精心打造出屬於自己的Borg系統(Mesos)時, Google也審時度勢地推出了來源於自身技術理論的新的開源工具。
2014年6月,谷歌雲計算專家埃裏克·布魯爾(Eric Brewer)在舊金山的發佈會爲這款新的開源工具揭牌,它的名字Kubernetes在希臘語中意思是船長或領航員,這也恰好與它在容器集羣管理中的作用吻合,即作爲裝載了集裝箱(Container)的衆多貨船的指揮者,負擔着全局調度和運行監控的職責。
雖然Google推出Kubernetes的目的之一是推廣其周邊的計算引擎(Google Compute Engine)和谷歌應用引擎(Google App Engine)。但Kubernetes的出現能讓更多的互聯網企業可以享受到連接衆多計算機成爲集羣資源池的好處。
Kubernetes對計算資源進行了更高層次的抽象,通過將容器進行細緻的組合,將最終的應用服務交給用戶。Kubernetes在模型建立之初就考慮了容器跨機連接的要求,支持多種網絡解決方案,同時在Service層次構建集羣範圍的SDN網絡。其目的是將服務發現和負載均衡放置到容器可達的範圍,這種透明的方式便利了各個服務間的通信,併爲微服務架構的實踐提供了平臺基礎。而在Pod層次上,作爲Kubernetes可操作的最小對象,其特徵更是對微服務架構的原生支持。
Kubernetes項目來源於Borg,可以說是集結了Borg設計思想的精華,並且吸收了Borg系統中的經驗和教訓。
Kubernetes作爲容器集羣管理工具,於2015年7月22日迭代到 v 1.0並正式對外公佈,這意味着這個開源容器編排系統可以正式在生產環境使用。與此同時,谷歌聯合Linux基金會及其他合作伙伴共同成立了CNCF基金會( Cloud Native Computing Foundation),並將Kuberentes 作爲首個編入CNCF管理體系的開源項目,助力容器技術生態的發展進步。Kubernetes項目凝結了Google過去十年間在生產環境的經驗和教訓,從Borg的多任務Alloc資源塊到Kubernetes的多副本Pod,從Borg的Cell集羣管理,到Kubernetes設計理念中的聯邦集羣,在Docker等高級引擎帶動容器技術興起和大衆化的同時,爲容器集羣管理提供獨了到見解和新思路。
kubeadm 概述
Kubeadm 是一個工具,它提供了 kubeadm init
以及 kubeadm join
這兩個命令作爲快速創建 kubernetes 集羣的最佳實踐。
kubeadm 通過執行必要的操作來啓動和運行一個最小可用的集羣。它被故意設計爲只關心啓動集羣,而不是準備節點環境的工作。同樣的,諸如安裝各種各樣的可有可無的插件,例如 Kubernetes 控制面板、監控解決方案以及特定雲提供商的插件,這些都不在它負責的範圍。
相反,我們期望由一個基於 kubeadm 從更高層設計的更加合適的工具來做這些事情;並且,理想情況下,使用 kubeadm 作爲所有部署的基礎將會使得創建一個符合期望的集羣變得容易。
一,環境準備
主機名 | 角色 | 配置 | 外網ip | 內網ip | 系統 | 內核版本 |
---|---|---|---|---|---|---|
k8s-m01 | master | 2核4G | 10.0.0.41 | 172.16.1.41 | centos7.7 | 4.4.224-1.el7.elrepo.x86_64 |
k8s-m02 | node | 2核4G | 10.0.0.42 | 172.16.1.42 | centos7.7 | 4.4.224-1.el7.elrepo.x86_64 |
1,修改主機名
[root@ c7-41 ~]# hostnamectl set-hostname k8s-m01
[root@ c7-42 ~]# hostnamectl set-hostname k8s-m02
2,做host解析
cat>>/etc/hosts<<\EOF
10.0.0.41 k8s-m01
10.0.0.42 k8s-m02
EOF
3,同步系統時間
echo "*/5* * * * /usr/sbin/ntpdate ntp1.aliyun.com >/dev/null 2>&1" >>/var/spool/cron/root
4.加載並優化內核參數
cat >/etc/sysctl.d/kubernetes.conf<<\EOF
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.ip_forward=1
net.ipv4.tcp_tw_recycle=0
vm.swappiness=0
vm.overcommit_memory=1
vm.panic_on_oom=0
fs.inotify.max_user_instances=8192
fs.inotify.max_user_watches=1048576
fs.file-max=52706963
fs.nr_open=52706963
net.ipv6.conf.all.disable_ipv6=1
net.netfilter.nf_conntrack_max=2310720
EOF
modprobe ip_vs_rr
modprobe br_netfilter
sysctl -p /etc/sysctl.d/kubernetes.conf
注:
tcp _tw. recycle和Kubernetes的NAT衝突,必須關閉, 否則會導致服務不通;
關閉不使用的IPV6協議棧,防止觸發docker BUG ;
5,關閉swap分區
如果開啓了swap分區, kubelet會啓動失敗(可以通過將參數-ail-swap-on設置爲false來忽略swap on) ,故需要在每個node節點機器上關團swap分區。
swapoff -a
sed -ri 's/.*swap.*/#&/' /etc/fstab
6,關閉防火牆和selinux
systemctl stop firewalld
systemctl disable firewalld
iptables -F && iptables -X && iptables -F -t nat && iptables -X -t nat
iptables -P FORWARD ACCEPT
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
7,安裝docker
yum -y install yum-utils device-mapper-persistent-data lvm2
wget -P /etc/yum.repos.d/ https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum makecache
yum -y install docker-ce-18.06.3.ce
#創建docker目錄
mkdir -p /etc/docker
#加速文件
cat> /etc/docker/daemon.json<<\EOF
{
"registry-mirrors": ["https://q3u0qv3z.mirror.aliyuncs.com"]
}
EOF
systemctl daemon-reload #重新載入
systemctl restart docker #啓動docker
systemctl enable docker #開機自啓
8,升級內核
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
yum --enablerepo=elrepo-kernel install kernel-lt -y
grub2-set-default 0 && grub2-mkconfig -o /etc/grub2.cfg
reboot #重啓服務器
二,Kubeadm部署集羣
1,安裝kubeadm,kubelet,kubectl
所有節點都安裝kubeadm,kubelet,kubectl,但是:node節點上的kubectl不是必須的。
● kubeadm:集羣管理命令。
● kubelet: 該組件運行在集羣中所有機器上,執行啓動pod和容器等操作。
● kubectl:與集羣通信的命令工具。
kubeadm不會爲你安裝或管理kubelet或kubectl ,因此你需要確保它們與kubeadm安裝的Kubernetes控制平面版本匹配。否則,就有發生版本傾斜的風險,這可能導致意外的錯誤行爲。然而, kubelet和控制平面之間的一個小版本傾斜是允許的,但是kubelet版本可能永遠不會超過API服務器版本。例如,運行1.7.0的kubelets應該完全兼容1.8.0 API服務器,反之則不然。
1.1,配置安裝源
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=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpghttps://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
1.2,清除和重載緩存
yum clean all
yum makecache
1.3,安裝指定的版本
yum install -y kubelet-1.18.0 kubeadm-1.18.0 kubectl-1.18.0
systemctl enable --now kubelet #開機自啓
2,配置初始化master
2.1,獲取默認配置文件
[root@ k8s-m01 ~]# kubeadm init --config kubeadm-init.yaml
2.2,修改配置文件
[root@ k8s-m01 ~] vim kubeadm-init.yaml
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: 10.0.0.41 #宿主機ip地址
bindPort: 6443
nodeRegistration:
criSocket: /var/run/dockershim.sock
name: k8s-m01
taints:
- effect: NoSchedule
key: node-role.kubernetes.io/master
---
apiServer:
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns:
type: CoreDNS
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: k8s.gcr.io
kind: ClusterConfiguration
kubernetesVersion: v1.18.0
networking:
dnsDomain: cluster.local
podSubnet: "10.244.0.0/16" #網絡插件flannel的默認網絡地址
serviceSubnet: 10.96.0.0/12
scheduler: {}
3,在兩臺服務器上拉取k8s鏡像
cat >k8s.images<<EOF
kube-apiserver:v1.18.0
kube-controller-manager:v1.18.0
kube-proxy:v1.18.0
kube-scheduler:v1.18.0
coredns:1.6.7
etcd:3.4.3-0
pause:3.2
EOF
for i in `cat k8s.images`
do
REPO=$(echo "$i"|awk -F ':' '{print $1}')
TAG=$(echo "$i"|awk -F ':' '{print $2}')
sudo docker pull registry.cn-beijing.aliyuncs.com/crazywjj/$i
sudo docker tag registry.cn-beijing.aliyuncs.com/crazywjj/$i k8s.gcr.io/$REPO:$TAG
sudo docker rmi -f registry.cn-beijing.aliyuncs.com/crazywjj/$i
done
4,初始化master
[root@ k8s-m01 ~]# kubeadm init --config kubeadm-init.yaml
W0525 17:37:07.630980 3103 configset.go:202] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io]
[init] Using Kubernetes version: v1.18.0
[preflight] Running pre-flight checks
[WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Starting the kubelet
[certs] Using certificateDir folder "/etc/kubernetes/pki"
[certs] Generating "ca" certificate and key
[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [k8s-m01 kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 10.0.0.41]
[certs] Generating "apiserver-kubelet-client" certificate and key
[certs] Generating "front-proxy-ca" certificate and key
[certs] Generating "front-proxy-client" certificate and key
[certs] Generating "etcd/ca" certificate and key
[certs] Generating "etcd/server" certificate and key
[certs] etcd/server serving cert is signed for DNS names [k8s-m01 localhost] and IPs [10.0.0.41 127.0.0.1 ::1]
[certs] Generating "etcd/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [k8s-m01 localhost] and IPs [10.0.0.41 127.0.0.1 ::1]
[certs] Generating "etcd/healthcheck-client" certificate and key
[certs] Generating "apiserver-etcd-client" certificate and key
[certs] Generating "sa" key and public key
[kubeconfig] Using kubeconfig folder "/etc/kubernetes"
[kubeconfig] Writing "admin.conf" kubeconfig file
[kubeconfig] Writing "kubelet.conf" kubeconfig file
[kubeconfig] Writing "controller-manager.conf" kubeconfig file
[kubeconfig] Writing "scheduler.conf" kubeconfig file
[control-plane] Using manifest folder "/etc/kubernetes/manifests"
[control-plane] Creating static Pod manifest for "kube-apiserver"
[control-plane] Creating static Pod manifest for "kube-controller-manager"
W0525 17:37:11.713054 3103 manifests.go:225] the default kube-apiserver authorization-mode is "Node,RBAC"; using "Node,RBAC"
[control-plane] Creating static Pod manifest for "kube-scheduler"
W0525 17:37:11.713877 3103 manifests.go:225] the default kube-apiserver authorization-mode is "Node,RBAC"; using "Node,RBAC"
[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s
[apiclient] All control plane components are healthy after 27.504287 seconds
[upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[kubelet] Creating a ConfigMap "kubelet-config-1.18" in namespace kube-system with the configuration for the kubelets in the cluster
[upload-certs] Skipping phase. Please see --upload-certs
[mark-control-plane] Marking the node k8s-m01 as control-plane by adding the label "node-role.kubernetes.io/master=''"
[mark-control-plane] Marking the node k8s-m01 as control-plane by adding the taints [node-role.kubernetes.io/master:NoSchedule]
[bootstrap-token] Using token: abcdef.0123456789abcdef
[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles
[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to get nodes
[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstrap-token] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstrap-token] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
[kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy
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 10.0.0.41:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:7f0f4b0bb51e0956662196f0cf81adb11a9c7f1b8161efd13e983ce976bf7046
5,配置kubectl命令
[root@ k8s-m01 ~] mkdir -p $HOME/.kube
[root@ k8s-m01 ~] sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
[root@ k8s-m01 ~] sudo chown $(id -u):$(id -g) $HOME/.kube/config
6,獲取pods列表命令
[root@ k8s-m01 ~] #
yum install -y bash-completion
echo 'source /usr/share/bash-completion/bash_completion' >> /etc/profile
source /etc/profile
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc
source ~/.bashrc
[root@ k8s-m01 ~] kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-66bff467f8-7gpvf 0/1 Pending 0 105s
kube-system coredns-66bff467f8-nz9mc 0/1 Pending 0 105s
kube-system etcd-k8s-m01 1/1 Running 0 114s
kube-system kube-apiserver-k8s-m01 1/1 Running 0 114s
kube-system kube-controller-manager-k8s-m01 1/1 Running 0 114s
kube-system kube-proxy-fknhs 1/1 Running 0 104s
kube-system kube-scheduler-k8s-m01 1/1 Running 0 115s
7,查看集羣健康狀態
[root@ k8s-m01 ~] kubectl get cs
NAME STATUS MESSAGE ERROR
controller-manager Healthy ok
scheduler Healthy ok
etcd-0 Healthy {"health":"true"}
[root@ k8s-m01 ~] kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-m01 NotReady master 3m21s v1.18.0
8,安裝網絡插件flannel
簡介:
Flannel是 CoreOS 團隊針對 Kubernetes 設計的一個覆蓋網絡(Overlay Network)工具,其目的在於幫助每一個使用 Kuberentes 的 CoreOS 主機擁有一個完整的子網。這次的分享內容將從Flannel的介紹、工作原理及安裝和配置三方面來介紹這個工具的使用方法。
Flannel通過給每臺宿主機分配一個子網的方式爲容器提供虛擬網絡,它基於Linux TUN/TAP,使用UDP封裝IP包來創建overlay網絡,並藉助etcd維護網絡的分配情況。
Flannel是一種基於overlay網絡的跨主機容器網絡解決方案 ,也就是將TCP數據包封裝在另一種網絡包裏面進行路由轉發和通信, Flannel是CoreOS開發專門用於docker多機互聯的一個工具,讓集羣中的不同節點主機創建的容器都具有全集羣唯一的虛擬ip地址。
Flannel使用go語言編寫。
Flannel實現原理
Flannel爲每個host分配-個subnet ,容器從這個subnet中分配IP ,這些IP可以在host間路由,容器間無需使用nat和端口映射即可實現跨主機通信。
每個subnet都是從一個更大的IP池中劃分的, flannel會在每個主機上運行一個叫flanneld的agent ,其職責就是從池子中分配subnet。
Flannel使用etcd存放網絡配置、已分配的subnet. host的IP等信息。
Flannel數據包在主機間轉發是由backend實現的,目前已經支持UDP、VxLAN、 host-gw. AWS VPC和GCE路由等多種backend.
8.1,下載yml
[root@ k8s-m01 ~] curl -o kube-flannel.yml https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
注意:
flannel默認會使用主機的第-一張物理網卡,如果你有多張網卡,需要通過配置單獨指定。修改kube-flannel.yml中的以下部分。
8.2,修改yml文件
[root@ k8s-m01 ~] vim kube-flannel.yml
[root@ k8s-m01 ~] sed -n '184,192p' kube-flannel.yml
containers:
- name: kube-flannel
image: quay.io/coreos/flannel:v0.12.0-amd64
command:
- /opt/bin/flanneld
args:
- --ip-masq
- --kube-subnet-mgr
- --iface=ens33
8.3,執行kube-flannel.yml
[root@ k8s-m01 ~]# kubectl apply -f kube-flannel.yml
8.4,檢查集羣狀態
[root@ k8s-m01 ~]# kubectl get pods --all-namespaces -o wide
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-system coredns-66bff467f8-fm24l 0/1 Pending 0 45m <none> <none> <none> <none>
kube-system coredns-66bff467f8-nfdhd 0/1 Pending 0 45m <none> <none> <none> <none>
kube-system etcd-k8s-m01 1/1 Running 0 45m 10.0.0.41 k8s-m01 <none> <none>
kube-system kube-apiserver-k8s-m01 1/1 Running 0 45m 10.0.0.41 k8s-m01 <none> <none>
kube-system kube-controller-manager-k8s-m01 1/1 Running 0 45m 10.0.0.41 k8s-m01 <none> <none>
kube-system kube-flannel-ds-amd64-2jv4n 0/1 Init:ErrImagePull 0 16s 10.0.0.41 k8s-m01 <none> <none>
kube-system kube-proxy-47pl6 1/1 Running 0 45m 10.0.0.41 k8s-m01 <none> <none>
kube-system kube-scheduler-k8s-m01 1/1 Running 0 45m 10.0.0.41 k8s-m01 <none> <none>
8.6
[root@ k8s-m01 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-m01 NotReady master 98m v1.18.0
[root@ k8s-m01 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 15m
[root@ k8s-m01 ~]# kubectl get cs
NAME STATUS MESSAGE ERROR
controller-manager Healthy ok
scheduler Healthy ok
etcd-0 Healthy {"health":"true"}
9,加入node節點,
節點(node)是工作負載(容器和pod等運行的地方,如果要向集羣添加新節點,請爲每臺機器執行以下操作:
● node節點執行1.1.2初始化準備
● 下載安裝鏡像.
● 執行kubeadm.join
9.1,在兩臺主機上,下載安裝鏡像
node上也是需要下載安裝一些鏡像的,需要下載的鏡像爲: kube-proxy, pause, flannel
cat >flannel.images<<EOF
v0.12.0-amd64
v0.12.0-arm
v0.12.0-arm64
v0.12.0-ppc64le
v0.12.0-s390x
EOF
for i in `cat flannel.images`
do
sudo docker pull registry.cn-beijing.aliyuncs.com/crazywjj/flannel:$i
sudo docker tag registry.cn-beijing.aliyuncs.com/crazywjj/flannel:$i quay.io/coreos/flannel:$i
sudo docker rmi -f registry.cn-beijing.aliyuncs.com/crazywjj/flannel:$i
done
9.2,在m02上執行,加入node節點
#不知道令牌,可以在主節點上運行
[root@ k8s-m01 ~] kubeadm token list
[root@ k8s-m02 ~] kubeadm join 10.0.0.41:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:7f0f4b0bb51e0956662196f0cf81adb11a9c7f1b8161efd13e983ce976bf7046
9.3,在master上查看node狀態
[root@ k8s-m01 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-m01 Ready master 164m v1.18.0
k8s-m02 Ready <none> 73s v1.18.0
9.4,查看pods狀態
[root@ k8s-m01 ~]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-66bff467f8-fm24l 1/1 Running 0 3h1m
coredns-66bff467f8-nfdhd 1/1 Running 0 3h1m
etcd-k8s-m01 1/1 Running 0 3h1m
kube-apiserver-k8s-m01 1/1 Running 0 3h1m
kube-controller-manager-k8s-m01 1/1 Running 0 3h1m
kube-flannel-ds-amd64-2d8lr 1/1 Running 0 18m
kube-flannel-ds-amd64-2jv4n 1/1 Running 0 136m
kube-proxy-47pl6 1/1 Running 0 3h1m
kube-proxy-mvbxk 1/1 Running 0 18m
kube-scheduler-k8s-m01 1/1 Running 0 3h1m
10,驗證kubernetes功能,
10.1,在master上創建測試文件
[root@ k8s-m01 ~] cat > nginx-ds.yml <<EOF
apiVersion: v1
kind: Service
metadata:
name: nginx-ds
labels:
app: nginx-ds
spec:
type: NodePort
selector:
app: nginx-ds
ports:
- name: http
port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nginx-ds
labels:
addonmanager.kubernetes.io/mode: Reconcile
spec:
selector:
matchLabels:
app: nginx-ds
template:
metadata:
labels:
app: nginx-ds
spec:
containers:
- name: my-nginx
image: daocloud.io/library/nginx:latest
ports:
- containerPort: 80
EOF
10.2,執行測試
[root@ k8s-m01 ~] kubectl create -f nginx-ds.yml
service/nginx-ds created
daemonset.apps/nginx-ds created
10.3,檢查個節點的pods ip連通性
#時間可能會稍長,由於網絡和服務器配置的問題
[root@ k8s-m01 ~] kubectl get pods -o wide|grep nginx-ds
nginx-ds-l7zvx 1/1 Running 0 20m 10.244.1.2 k8s-m02 <none> <none>
10.4,測試聯通
[root@ k8s-m01 ~] ping -c 3 10.244.1.2,
10.5,檢查服務ip和端口的可達性
[root@ k8s-m01 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3h30m
nginx-ds NodePort 10.104.30.77 <none> 80:30588/TCP 24m
可見的nginx-ds信息:
● service cluster ip:10.104.30.77
● 服務端口:80
● nodeport端口:30588
10.6,檢查服務的nodeport可達性
[root@ k8s-m01 ~] curl -Is 10.0.0.42:30588
HTTP/1.1 200 OK
Server: nginx/1.17.10
Date: Mon, 25 May 2020 13:11:12 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 14 Apr 2020 14:19:26 GMT
Connection: keep-alive
ETag: "5e95c66e-264"
Accept-Ranges: bytes
11,移除node節點
11.1,在master節點執行
[root@ k8s-m01 ~]# kubectl drain k8s-m02 --delete-local-data --force --ignore-daemonsets
[root@ k8s-m01 ~]# kubectl delete node k8s-m02
11.2,在node節點執行
[root@ k8s-m02 ~] kubeadm reset
[root@ k8s-m02 ~] systemctl stop kubelet
[root@ k8s-m02 ~] systemctl stop docker
[root@ k8s-m02 ~] rm -rf /var/lib/cni/ /var/lib/kubelet/* /etc/cni/
[root@ k8s-m02 ~] ifconfig cni0 down
[root@ k8s-m02 ~] ifconfig flannel.1 down
[root@ k8s-m02 ~] ifconfig docker0 down
[root@ k8s-m02 ~] ip link delete cni0
[root@ k8s-m02 ~] ip link delete flannel.1
[root@ k8s-m02 ~] systemctl start docker
11.3,查看容器
docker ps -a
三,Dashboard界面
Dashboard 是基於網頁的 Kubernetes 用戶界面。可以使用 Dashboard 將容器應用部署到 Kubernetes 集羣中,也可以對容器應用排錯,還能管理集羣本身及其附屬資源。可以使用 Dashboard 獲取運行在集羣中的應用的概覽信息,也可以創建或者修改 Kubernetes 資源(如 Deployment,Job,DaemonSet 等等)。例如,您可以對 Deployment 實現彈性伸縮、發起滾動升級、重啓 Pod 或者使用嚮導創建新的應用。
在kubernetes Dashboard中可以查看集羣中應用的運行狀態,也能夠創建和修改各種kubernetes資源(比如Deployment,Job,Daemonset等等),用戶可以對Deployment實現彈性伸縮,執行滾動升級,重啓pod或者使用嚮導創建新的應用。
可以說,kubernetes Dashboard提供了kubectl的絕大部分功能。
1,全面的羣集管理:命名空間,節點,窗格,副本集,部署,存儲,RBAC創建修改等
2,快速且始終如一的即時更新:無需刷新頁面即可查看最新信息
3,快速查看集羣運行狀況:實時圖表可幫助快速跟蹤性能不佳的資源
4,易於CRUD和擴展:加上內聯API文檔,可以輕鬆瞭解每個字段的作用
5,簡單的OpenID集成:無需特殊代理
Dashboard 同時展示了kubernetes集羣中的資源狀態信息和所有報錯信息。
1,下載 dashboard 文件
[root@ k8s-m01 ~] curl -o dashboard-recommended.yaml https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-rc7/aio/deploy/recommended.yaml
[root@ k8s-m01 ~] kubectl apply -f dashboard-recommended.yaml
1.1,查看運行狀態
[root@ k8s-m01 ~] kubectl get pods -n kubernetes-dashboard
NAME READY STATUS RESTARTS AGE
dashboard-metrics-scraper-dc6947fbf-r9hkk 1/1 Running 0 6m29s
kubernetes-dashboard-5d4dc8b976-8grfp 1/1 Running 0 6m30s
1.2,查看kubernetes-dashboard所有信息
[root@ k8s-m01 ~] kubectl get all -n kubernetes-dashboard
NAME READY STATUS RESTARTS AGE
pod/dashboard-metrics-scraper-dc6947fbf-zz6xw 1/1 Running 0 18m
pod/kubernetes-dashboard-5d4dc8b976-z4kn6 1/1 Running 0 18m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/dashboard-metrics-scraper ClusterIP 10.110.248.70 <none> 8000/TCP 22m
service/kubernetes-dashboard ClusterIP 10.103.148.191 <none> 443/TCP 22m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/dashboard-metrics-scraper 1/1 1 1 22m
deployment.apps/kubernetes-dashboard 1/1 1 1 22m
NAME DESIRED CURRENT READY AGE
replicaset.apps/dashboard-metrics-scraper-dc6947fbf 1 1 1 22m
replicaset.apps/kubernetes-dashboard-5d4dc8b976 1 1 1 22m
2,訪問 dashboard
dashboard 只允許通過 https 訪問,如果使用 kube proxy 則必須監聽 localhost 或 127.0.0.1。對於 NodePort 沒有這個限制,但是僅建議在開發環境中使用。對於不滿足這些條件的登錄訪問,在登錄成功後瀏覽器不跳轉,始終停在登錄界面。
訪問方式:
Dashboard的github https://github.com/kubernetes/dashboard/blob/master/docs/user/accessing-dashboard/1.7.x-and-above.md
kubectl proxy:
kubectl proxy在您的機器和Kubernetes API服務器之間創建代理服務器。默認情況下,只能在本地(從啓動它的計算機上)訪問它。
kubectl port-forward:
通過端口轉發映射本地端口到指定的應用端口,從而訪問集羣中的應用程序(Pod)。
NodePort:
這種方法只推薦使用在一個node節點的方案,在大多數的環境都需要多個node節點,因此這種方法沒有什麼實用價值,不建議使用。
API Server:
如果Kubernetes API服務器是公開的並且可以從外部訪問,則可以直接在以下位置訪問儀表板: https://:/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/
注意:
僅當您選擇在瀏覽器中安裝用戶證書時,纔可以使用這種方式訪問Dashboard。在示例中,可以使用kubeconfig文件用於聯繫API服務器的證書。
Ingress
採用API Server訪問: https://10.0.0.41:6443/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/
我們使用的是system:anonymous用戶來訪問位於kube-system命名空間中的名爲https:kubernetes-dashboard的service資源。這個用戶沒有權限訪問,所以被拒絕了。
3,生成瀏覽器訪問證書
dashboard 默認只支持 token 認證(不支持 client 證書認證),所以如果使用 Kubeconfig 文件,需要將 token 寫入到該文件。
創建證書:
首先需要確認kubectl命令的配置文件,默認情況下爲/etc/kubernetes/admin.conf,而且已經自動創建在$HOME/.kube/config中,如果沒有創建則需要手動賦值。
3.1,創建kubectl配置文件
[root@ k8s-m01 ~] cat $HOME/.kube/config
3.2,確認集羣配置,生成p12格式的瀏覽器證書
[root@ k8s-m01 ~] cd /etc/kubernetes/pki
[root@ k8s-m01 pki] grep 'client-certificate-data' ~/.kube/config | head -n 1 | awk '{print $2}' | base64 -d > dashboard.crt
[root@ k8s-m01 pki] grep 'client-key-data' ~/.kube/config | head -n 1 | awk '{print $2}' | base64 -d > dashboard.key
3.3,生成p12證書,設置密碼(正確設置密碼)在導入瀏覽器時使用
[root@ k8s-m01 pki] openssl pkcs12 -export -clcerts -inkey dashboard.key -in dashboard.crt -out dashboard.p12 -name "kubernetes-client"
Enter Export Password:
Verifying - Enter Export Password:
4,將生成的dashboard.p12證書下載到Windows桌面上,然後導入瀏覽器
谷歌(Google)或者火狐(Firefox)
5,登錄dashboard
5.1,創建登錄dashboard的token和kubeconfig配置文件
方法1:
可以使用輸出的token,登錄dashboard
[root@ k8s-m01 pki]#
kubectl create sa dashboard-admin -n kube-system
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
ADMIN_SECRET=$(kubectl get secrets -n kube-system | grep dashboard-admin | awk '{print $1}')
DASHBOARD_LOGIN_TOKEN=$(kubectl describe secret -n kube-system ${ADMIN_SECRET} | grep -E '^token' | awk '{print $2}')
echo ${DASHBOARD_LOGIN_TOKEN}
方法2:
將Dashboard.Kubeconfig文件下載到電腦端,用生成的Dashboard.Kubeconfig登錄dashboard
[root@ k8s-m01 pki]#
cd /etc/kubernetes/pki
KUBE_APISERVER="https://10.0.0.41:6443"
DASHBOARD_LOGIN_TOKEN=$(kubectl describe secret -n kube-system ${ADMIN_SECRET} | grep -E '^token' | awk '{print $2}')
# 設置集羣參數
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/pki/ca.crt \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=dashboard.kubeconfig
# 設置客戶端認證參數,使用上面創建的 Token
kubectl config set-credentials dashboard_user \
--token=${DASHBOARD_LOGIN_TOKEN} \
--kubeconfig=dashboard.kubeconfig
# 設置上下文參數
kubectl config set-context default \
--cluster=kubernetes \
--user=dashboard_user \
--kubeconfig=dashboard.kubeconfig
# 設置默認上下文
kubectl config use-context default --kubeconfig=dashboard.kubeconfig