本文原始地址(gitbook格式):https://farmer-hutao.github.io/k8s-source-code-analysis/prepare/debug-environment.html
本項目github地址:https://github.com/farmer-hutao/k8s-source-code-analysis
1. 概述
大家注意哦,不一定要先搭建好環境再看源碼,大可以先看一個組件,感覺差不多理解了,想要run一把,想要改幾行試試的時候回過頭來搭建k8s環境。
當然,大家開始看源碼的時候,我相信各位都是搭建過不少次k8s集群,敲過N多次kubectl命令了,所以下面我不會解釋太基礎的命令是做什么的。
今天我們要做的是搭建一個單機版的k8s環境,用於后面的學習。雖然k8s的環境搭建沒有openstack來的復雜,但是由於網絡等亂七八糟的問題,在國內手動搭建一個五臟俱全的k8s也不算太容易,一個不小心就會被亂七八遭的障礙磨滅興趣。今天看看我能不能讓大家覺得這個過程無痛吧~
2. kubeadm簡介
選擇一個好的工具很重要!大家在剛開始學習k8s的時候應該都用二進制文件一步一步搭建過集群吧,那個過程是不是很酸爽?手動一步一步搭建環境對於初學者來說確實大有裨益,可以了解各個組件的細節。我已經懶掉了,我決定從眾多k8s自動化安裝方案中選擇一個來搭建這次的k8s環境。
kubeadm是Kubernetes官方提供的用於快速安裝Kubernetes集群的工具,這不是一個單獨的項目哦,我們在kubernetes源碼里可以看到這個組件(kubernetes/cmd/kubeadm/
):
kubeadm這個工具可以通過簡單的kubeadm init
和kubeadm join
命令來創建一個kubernetes集群,kubeadm提供的其他命令都比較通俗易懂:
kubeadm init
啟動一個master節點;kubeadm join
啟動一個node節點,加入master;kubeadm upgrade
更新集群版本;kubeadm config
從1.8.0版本開始已經用處不大,可以用來view一下配置;kubeadm token
管理kubeadm join
的token;kubeadm reset
把kubeadm init
或kubeadm join
做的更改恢復原狀;kubeadm version
打印版本信息;kubeadm alpha
預覽一些alpha特性的命令。
關於kubeadm的成熟度官方有一個表格:
Area | Maturity Level |
---|---|
Command line UX | GA |
Implementation | GA |
Config file API | beta |
CoreDNS | GA |
kubeadm alpha subcommands | alpha |
High availability | alpha |
DynamicKubeletConfig | alpha |
Self-hosting | alpha |
主要特性其實都已經GA了,雖然還有一些小特性仍處於活躍開發中,但是整體已經接近准生產級別了。對於我們的場景來說用起來已經綽綽有余!
3. 操作系統准備
我們先使用一個機子來裝,后面需要拓展可以增加節點,使用kubeadm join
可以很輕松擴展集群。
3.1. 系統信息
- 內存:2G
- CPU:2
- 磁盤:20G
系統版本和內核版本如下所示,大家不需要嚴格和我保持一致,不要使用太舊的就行了。
# cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core)
# uname -r
3.10.0-862.9.1.el7.x86_64
3.2. 配置selinux和firewalld
# Set SELinux in permissive mode setenforce 0 sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config # Stop and disable firewalld systemctl disable firewalld --now
3.3. 系統參數與內核模塊
# 修改內核參數 cat <<EOF > /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 EOF sysctl --system # 加載內核模塊 modprobe br_netfilter lsmod | grep br_netfilter
3.4. 配置yum源
# base repo cd /etc/yum.repos.d mv CentOS-Base.repo CentOS-Base.repo.bak curl -o CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo sed -i 's/gpgcheck=1/gpgcheck=0/g' /etc/yum.repos.d/CentOS-Base.repo # docker repo curl -o docker-ce.repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # k8s repo cat <<EOF > /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=0 repo_gpgcheck=0 gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF # update cache yum clean all yum makecache yum repolist
最終我們可以看到這些repo:
3.5. 禁用swap
swapoff -a
echo "vm.swappiness = 0">> /etc/sysctl.conf sysctl -p
4. 安裝docker
先看一下有哪些可用版本:yum list docker-ce --showduplicates | sort -r
- 我們選擇一個版本安裝:
yum install docker-ce-<VERSION STRING>
- 這里我選擇18.03.1,所以我用的命令是:
yum install docker-ce-18.06.3.ce
- 可以用rpm命令看一下docker-ce這個rpm包帶來了哪些文件:
- 啟動docker:
systemctl enable docker --now
- 查看服務狀態:
systemctl status docker
5. 安裝kubeadm、kubelet和kubectl
kubeadm不管kubelet和kubectl,所以我們需要手動安裝kubelet和kubectl:
yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
如果你看到這個教程的時候yum源里已經有了1.14版本的kubeadm,那么要么你裝新版本,要么通過上面裝docker同樣的方式指定1.13版本安裝,我這里使用的是1.13.3。
最后啟動kubelet:
systemctl enable --now kubelet
6. 鏡像准備
為了解決國內普遍訪問不到k8s.gcr.io的問題,我們從mirrorgooglecontainers下載image,然后打個tag來繞過網絡限制:
docker pull docker.io/mirrorgooglecontainers/kube-apiserver-amd64:v1.13.3
docker tag docker.io/mirrorgooglecontainers/kube-apiserver-amd64:v1.13.3 k8s.gcr.io/kube-apiserver:v1.13.3
docker pull docker.io/mirrorgooglecontainers/kube-controller-manager-amd64:v1.13.3
docker tag docker.io/mirrorgooglecontainers/kube-controller-manager-amd64:v1.13.3 k8s.gcr.io/kube-controller-manager:v1.13.3
docker pull docker.io/mirrorgooglecontainers/kube-scheduler-amd64:v1.13.3
docker tag docker.io/mirrorgooglecontainers/kube-scheduler-amd64:v1.13.3 k8s.gcr.io/kube-scheduler:v1.13.3
docker pull docker.io/mirrorgooglecontainers/kube-proxy-amd64:v1.13.3
docker tag docker.io/mirrorgooglecontainers/kube-proxy-amd64:v1.13.3 k8s.gcr.io/kube-proxy:v1.13.3
docker pull docker.io/mirrorgooglecontainers/pause-amd64:3.1
docker tag docker.io/mirrorgooglecontainers/pause-amd64:3.1 k8s.gcr.io/pause:3.1
docker pull docker.io/mirrorgooglecontainers/etcd-amd64:3.2.24
docker tag docker.io/mirrorgooglecontainers/etcd-amd64:3.2.24 k8s.gcr.io/etcd:3.2.24
docker pull docker.io/coredns/coredns:1.2.6
docker tag docker.io/coredns/coredns:1.2.6 k8s.gcr.io/coredns:1.2.6
7. 安裝k8s master
kubeadm init --pod-network-cidr=10.100.0.0/16
如上,跑kubeadm init
命令后等幾分鍾。
如果遇到報錯,對着錯誤信息修正一下。比如沒有關閉swap會遇到error,系統cpu不夠會遇到error,網絡不通等等都會出錯,仔細看一下錯誤信息一般都好解決~
跑完上面的init命令后,會看到類似如下的輸出:
Your Kubernetes master 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/ You can now join any number of machines by running the following on each node as root: kubeadm join 192.168.19.100:6443 --token i472cq.tr9a81qxnyqc5zj2 --discovery-token-ca-cert-hash sha256:acba957db29e0efbffe2cf4e484521b3b7e0f9d5c2ab7f9db68a5e31565d0d66
上面輸出告訴我們還需要做一些工作:
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config # flannel kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/bc79dd1505b0c8681ece4de4c0d86c5cd2643275/Documentation/kube-flannel.yml
稍等一會,應該可以看到node狀態變成ready:
# kubectl get node
NAME STATUS ROLES AGE VERSION
kube-master Ready master 23m v1.13.3
如果你的環境遲遲都是NotReady狀態,可以kubectl get pod -n kube-system
看一下pod狀態,一般可以發現問題,比如flannel的鏡像下載失敗啦~
當node Ready的時候,我們可以看到pod也全部ready了:
再看一下核心組件狀態:
最后注意到kube-master這個node上有一個Taint:
# kubectl describe node kube-master | grep Taints
Taints: node-role.kubernetes.io/master:NoSchedule
默認master節點是不跑業務pod的,我們暫時只有一個node,所以先去掉這個Taint:
# kubectl taint node kube-master node-role.kubernetes.io/master-
node/kube-master untainted
# kubectl describe node kube-master | grep Taints
Taints: <none>
8. 環境驗證
我們來跑一個pod,證明環境正常可用了:
寫一個yaml:
apiVersion: apps/v1 kind: Deployment metadata: name: mytomcat spec: replicas: 1 selector: matchLabels: app: mytomcat template: metadata: name: mytomcat labels: app: mytomcat spec: containers: - name: mytomcat image: tomcat:8 ports: - containerPort: 8080
如上內容保存為tomcat-deploy.yaml
,執行kubectl create -f tomcat-deploy.yaml
,然后看pod狀態:
確認了,是熟悉的Running,哈哈,基本算大功告成了!最后我們看一下tomcat服務能不能訪問到:
很完美,如果加個svc配置,就能夠通過瀏覽器訪問到湯姆貓界面了!