時隔大半年旱爆,我又回來了,這回帶來的是最近非尘阶拢火的容器編排工具——kubernetes
先附上docker 官網(wǎng)和kubernetes中文社區(qū)鏈接怀伦,我搭建k8s的苦逼之路也是從這里開始的,想了解docker 和kubernetes是什么的朋友或者是初學(xué)者可以先看看
在去年年底公司領(lǐng)導(dǎo)提出的IT信息化變革, 緊跟新一代信息技術(shù)發(fā)展趨勢山林,利用信息技術(shù)提高業(yè)務(wù)生產(chǎn)效率房待。所以我們嘗試采用kubernetes、PaaS捌朴、DevOps作為支撐吴攒,來實現(xiàn)全新的IT信息化建設(shè)张抄。
那在這個系列砂蔽,就是把我整個搭建kubernetes過程以及過程中遇到的坑和教訓(xùn)以及解決方法等記錄下來,方便自己和大家以后遇到相似的問題能得以解決署惯,在接下來的文章里左驾,為了書寫方便,kubernetes我就用k8s來替代了极谊。
我在一開始急于求成诡右,想看看完整的一個k8s平臺,于是采用了GitHub上面的一個開源腳本部署項目——kubekit 快速離線部署工具轻猖。
這個工具采用腳本的方式帆吻,通過腳本控制kubeadm以及可視化界面來完成master和node的部署,極大降低了k8s的入學(xué)門檻咙边,方便一票的初學(xué)者窺探k8s世界猜煮,我就是其中一個。败许。哈哈
感興趣的童鞋可以直接去GitHub上學(xué)習(xí)王带,上面有詳細的安裝教程,最高支持k8s1.9的版本市殷,簡單易用愕撰。
在玩膩了kubekit自動部署以后,我們我們想直接自己使用kubeadm來部署我們的k8s醋寝,想自己手動部署k8s一個很大的原因是因為使用kubekit控制臺無法設(shè)置認證和授權(quán)搞挣,也不知道是什么原因,修改了apiserver配置文件以后就怎么也起不來了音羞。因此囱桨,下面我詳細解釋一下我們使用kubeadm來離線部署k8s集群過程。
我們的k8s版本是目前比較新的1.10黄选,首先準備三臺linux 蝇摸,機子硬件要就最好4核8G硬盤30G以上婶肩,vm或者別的虛擬機的話酌情降低,系統(tǒng)我用的是公司特意升級過的的redhat 7.2貌夕,centos7以上的機子也是可以的律歼,并且已經(jīng)安裝好了docker ,這里我們使用的是docker-ce-17.03.0?CE版本啡专,附上下載地址可能需要翻墻险毁。。们童。
當然你也可以直接動過yum安裝
安裝完成后執(zhí)行
systemctl start docker &&?systemctl enable docker
通過docker version 可以查看docker的版本
Client: Version: 17.03.2-ce API version: 1.27 Go version: go1.7.5 Git commit: f5ec1e2 Built: Tue Jun 27 02:21:36 2017 OS/Arch: linux/amd64Server: Version: 17.03.2-ce API version: 1.27 (minimum version 1.12) Go version: go1.7.5 Git commit: f5ec1e2 Built: Tue Jun 27 02:21:36 2017 OS/Arch: linux/amd64 Experimental: false
安裝k8s之前三臺機子的環(huán)境得配好
每一臺機子執(zhí)行以下命令
systemctl stop firewalld && systemctl disable firewalld
setenforce 0
echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables
echo 1 > /proc/sys/net/bridge/bridge-nf-call-ip6tables
echo 1 > /proc/sys/net/ipv4/ip_forward
sysctl -w net.bridge.bridge-nf-call-iptables=1
vim /etc/sysctl.conf
net.ipv4.ip_forward=1
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
sysctl -p
swapoff -a
有人可能疑惑畔况,為什么要關(guān)掉swap,那是跟k8s的設(shè)計初衷有關(guān)慧库,k8s的想法是將實例緊密包裝到盡可能接近100%跷跪。 所有的部署應(yīng)該與CPU /內(nèi)存限制固定在一起。 所以如果調(diào)度程序發(fā)送一個pod到一臺機器齐板,它不應(yīng)該使用交換吵瞻。 設(shè)計者不想交換,因為它會減慢速度甘磨。
所以關(guān)閉swap主要是為了性能考慮橡羞。當然為了一些節(jié)省資源的場景,比如運行容器數(shù)量較多济舆,可添加kubelet參數(shù)?--fail-swap-on=false來解決卿泽。
摘抄自https://blog.csdn.net/liuliuzi_hz/article/details/79076553
安裝k8s需要以下安裝包
socat-1.7.3.2-2.el7.x86_64.rpm、kubernetes-cni-0.6.0-0.x86_64.rpm滋觉、kubeadm-1.10.0-0.x86_64.rpm签夭、kubectl-1.10.0-0.x86_64.rpm、kubelet-1.10.0-0.x86_64.rpm椎瘟、kubernetes-cni-0.6.0-0.x86_64.rpm
到安裝包目錄下執(zhí)行yum install -y *.rpm 來完成k8s組件的安裝覆致。
因為是離線安裝,k8s需要的相關(guān)鏡像我們也得準備好
Master
docker load < k8s_images/docker_images/etcd-amd64_v3.1.10.tar
docker load < k8s_images/docker_images/flannel\:v0.9.1-amd64.tar
docker load < k8s_images/docker_images/k8s-dns-dnsmasq-nanny-amd64_v1.14.7.tar
docker load < k8s_images/docker_images/k8s-dns-kube-dns-amd64_1.14.7.tar
docker load < k8s_images/docker_images/k8s-dns-sidecar-amd64_1.14.7.tar
docker load < k8s_images/docker_images/kube-apiserver-amd64_v1.9.0.tar
docker load < k8s_images/docker_images/kube-controller-manager-amd64_v1.9.0.tar
docker load < k8s_images/docker_images/kube-scheduler-amd64_v1.9.0.tar
docker load < k8s_images/docker_images/kube-proxy-amd64_v1.9.0.tar
docker load < k8s_images/docker_images/pause-amd64_3.0.tar
docker load < k8s_images/kubernetes-dashboard_v1.8.1.tar
nodes
docker load < k8s_images/docker_images/kube-proxy-amd64_v1.9.0.tar
docker load < k8s_images/docker_images/pause-amd64_3.0.tar
docker load < k8s_images/kubernetes-dashboard_v1.8.1.tar
docker load < flannel.tar
因為導(dǎo)入進去的鏡像鏡像名和kubeadm需要安裝的鏡像名不同肺蔚,因此需要修改相應(yīng)的鏡像名煌妈,例:docker tag IMAGESname:xxx quay.io/coreos/flannel:v0.9.1
這里也可以通過腳本的方式去一鍵改名:
vim?auto_changeName.sh
images=(gcr.io/google_containers
? ? k8s-dns-kube-dns-amd64:1.14.9
? ? k8s-dns-sidecar-amd64:1.14.9
? ? k8s-dns-dnsmasq-nanny-amd64:1.14.9
? ? kube-proxy-amd64:v1.10.0
? ? kube-apiserver-amd64:v1.10.0
? ? kube-controller-manager-amd64:v1.10.0
? ? kube-scheduler-amd64:v1.10.0
? ? etcd-amd64:3.1.12
? ? kubernetes-dashboard-amd64:v1.8.3
? ? pause-amd64:3.1
)
for imageName in ${images[@]} ;
do
? ? docker tag gcr.io/google_containers/$imageName k8s.gcr.io/$imageName
? ? docker rmi -f gcr.io/google_containers/$imageName
done
然后賦予腳本執(zhí)行權(quán)限chmod +x *.sh?
執(zhí)行./*.sh
注意在執(zhí)行kubeadm init 之前,務(wù)必檢查docker 的Cgroup Driver宣羊,如果是cgroupfs的話璧诵,則每一臺節(jié)點都執(zhí)行
sed -i -e 's/cgroup-driver=systemd/cgroup-driver=cgroupfs/g' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
systemctl daemon-reload && systemctl restart kubelet
kubeadm reset
Master
在Master上執(zhí)行kubeadm init --kubernetes-version=v1.10.0 --pod-network-cidr=10.244.0.0/16
kubernetes默認支持多重網(wǎng)絡(luò)插件如flannel、weave仇冯、calico之宿,這里使用flanne,就必須要設(shè)置--pod-network-cidr參數(shù)苛坚,10.244.0.0/16是kube-flannel.yml里面配置的默認網(wǎng)段比被,如果需要修改的話色难,需要把kubeadm init的--pod-network-cidr參數(shù)和后面的kube-flannel.yml里面修改成一樣的網(wǎng)段就可以了〉茸海——https://segmentfault.com/a/1190000012755243
如果kubeadm init安裝失敗枷莉,可以通過kubeadm reset 重置,通過journalctl -xeu kubelet 查看服務(wù)啟動日志尺迂。
安裝成功應(yīng)該會有kubeadm join ip:6443 --token n95wls.h1ifw0ln1mzlmfhu --discovery-token-ca-cert-hash sha256:XXX笤妙。
記得保存以上信息,因為node節(jié)點加入需要使用噪裕。
如果忘記了蹲盘,可以在master上通過kubeadmin token list得到
默認token 24小時就會過期,后續(xù)的機器要加入集群需要重新生成token膳音。使用命令kubeadm?token?create
按照上面提示召衔,此時root用戶還不能使用kubelet控制集群需要,配置下環(huán)境變量
對于非root用戶
mkdir -p$HOME/.kube
cp -i/etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g)$HOME/.kube/config
對于root用戶
export?KUBECONFIG=/etc/kubernetes/admin.conf
也可以直接放到~/.bash_profile
echo?"export KUBECONFIG=/etc/kubernetes/admin.conf"?>> ~/.bash_profile
source一下環(huán)境變量
source?~/.bash_profile
然后執(zhí)行kubectl get nodes 查看節(jié)點狀態(tài)严蓖,不出意外的話應(yīng)該是NoReady,那是因為沒有網(wǎng)絡(luò)組件薄嫡。我們使用fannel
下載此文件
wget https://raw.githubusercontent.com/coreos/flannel/v0.9.1/Documentation/kube-flannel.yml
若要使用的是自己的私服鏡像氧急,或者修改網(wǎng)段颗胡,需要kubeadm --pod-network-cidr=和這里同步
vim kube-flannel.yml
修改imges、network項
執(zhí)行
kubectl create??-f?kube-flannel.yml
通過kubectl get pods --all-namespaces 查看flannelpod狀態(tài)
如果沒有問題的話再次執(zhí)行kubectl get nodes 會發(fā)現(xiàn)master節(jié)點已經(jīng)變成Ready吩坝。
如果部署flannel出現(xiàn)問題毒姨,可以通過
kubectl describe pod flannel -n namespaces?//查看部署日志
修改kube-flannel.yml后可以通過kubectl apply ?-f?kube-flannel.yml來更新
多半是因為網(wǎng)絡(luò)地址沒寫對或者鏡像地址錯誤導(dǎo)致的。
node
使用剛剛kubeadm后的kubeadm join --xxx
如果失敗钉寝,可能是因為忘記修改cgroup弧呐,一定要學(xué)會查看錯誤日志
sed -i -e 's/cgroup-driver=systemd/cgroup-driver=cgroupfs/g' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
systemctl daemon-reload && systemctl restart kubelet
kubeadm reset
然后重新join一次,不出意外地話應(yīng)該會出現(xiàn)success嵌纲。
通過kubectl get nodes 查看master和node狀態(tài)俘枫。kubernetes基本集群安裝完成。如果需要添加新的節(jié)點亦是如此逮走。
部署kubernetes-dashboard
雖然這個組件在我參考的文章中說的很不好用鸠蚪,功能太少,但是在我看來還是非常好用的师溅,對于初學(xué)者 配合heapster查看pod和各種deployment以及節(jié)點狀態(tài)還是非常方便的茅信,更新和刪除以及查看日志都很方便
部署kubernetes-dashboard.yaml
apiVersion: v1
kind: Secret
metadata:
? labels:
? ? k8s-app: kubernetes-dashboard
? name: kubernetes-dashboard-certs
? namespace: kube-system
type: Opaque
---
# ------------------- Dashboard Service Account ------------------- #
apiVersion: v1
kind: ServiceAccount
metadata:
? labels:
? ? k8s-app: kubernetes-dashboard
? name: kubernetes-dashboard
? namespace: kube-system
---
# ------------------- Dashboard Role & Role Binding ------------------- #
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
? name: kubernetes-dashboard-minimal
? namespace: kube-system
rules:
? # Allow Dashboard to create 'kubernetes-dashboard-key-holder' secret.
- apiGroups: [""]
? resources: ["secrets"]
? verbs: ["create"]
? # Allow Dashboard to create 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
? resources: ["configmaps"]
? verbs: ["create"]
? # Allow Dashboard to get, update and delete Dashboard exclusive secrets.
- apiGroups: [""]
? resources: ["secrets"]
? resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs"]
? verbs: ["get", "update", "delete"]
? # Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
? resources: ["configmaps"]
? resourceNames: ["kubernetes-dashboard-settings"]
? verbs: ["get", "update"]
? # Allow Dashboard to get metrics from heapster.
- 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: RoleBinding
metadata:
? name: kubernetes-dashboard-minimal
? namespace: kube-system
roleRef:
? apiGroup: rbac.authorization.k8s.io
? kind: Role
? name: kubernetes-dashboard-minimal
subjects:
- kind: ServiceAccount
? name: kubernetes-dashboard
? namespace: kube-system
---
# ------------------- Dashboard Deployment ------------------- #
kind: Deployment
apiVersion: apps/v1beta2
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: 192.168.220.84/kubernetes/kubernetes-dashboard-amd64:v1.8.3
? ? ? ? ports:
? ? ? ? - containerPort: 8443
? ? ? ? ? protocol: TCP
? ? ? ? args:
? ? ? ? ? - --auto-generate-certificates
? ? ? ? ? - --authentication-mode=basic
? ? ? ? ? # Uncomment the following line to manually specify Kubernetes API server Host
? ? ? ? ? # If not specified, Dashboard will attempt to auto discover the API server and connect
? ? ? ? ? # to it. Uncomment only if the default does not work.
? ? ? ? ? # - --apiserver-host=http://my-address:port
? ? ? ? volumeMounts:
? ? ? ? - name: kubernetes-dashboard-certs
? ? ? ? ? mountPath: /certs
? ? ? ? ? # Create on-disk volume to store exec logs
? ? ? ? - 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
? ? ? # Comment the following tolerations if Dashboard must not be deployed on master
? ? ? tolerations:
? ? ? - key: node-role.kubernetes.io/master
? ? ? ? effect: NoSchedule
---
# ------------------- Dashboard Service ------------------- #
kind: Service
apiVersion: v1
metadata:
? labels:
? ? k8s-app: kubernetes-dashboard
? name: kubernetes-dashboard
? namespace: kube-system
spec:
? type: NodePort
? #type: ExternalName
? #externalName: static.otherdomain.com
? ports:
? ? - port: 443
? ? ? targetPort: 8443
? ? ? nodePort: 31234
? selector:
? ? k8s-app: kubernetes-dashboard
nodeport端口范圍30000-32767
31234就是我的映射端口,根docker run -d xxx:xxx差不多
部署kubernetes-dashboard
kubectl apply -f?kubernetes-dashboard.yaml
部署kubernetes-dashboard插件heapster.yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
? name: heapster
? namespace: kube-system
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
? name: heapster
subjects:
? - kind: ServiceAccount
? ? name: heapster
? ? namespace: kube-system
roleRef:
? kind: ClusterRole
? name: system:heapster
? apiGroup: rbac.authorization.k8s.io
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
? name: heapster
? namespace: kube-system
spec:
? replicas: 1
? template:
? ? metadata:
? ? ? labels:
? ? ? ? task: monitoring
? ? ? ? k8s-app: heapster
? ? spec:
? ? ? serviceAccountName: heapster
? ? ? containers:
? ? ? - name: heapster
? ? ? ? image: 192.168.220.84/third_party/heapster-amd64:v1.3.0
? ? ? ? imagePullPolicy: IfNotPresent
? ? ? ? command:
? ? ? ? - /heapster
? ? ? ? - --source=kubernetes:https://kubernetes.default
? ? ? ? - --sink=influxdb:http://monitoring-influxdb.kube-system.svc:8086
---
apiVersion: v1
kind: Service
metadata:
? labels:
? ? task: monitoring
? ? # For use as a Cluster add-on (https://github.com/kubernetes/kubernetes/tree/master/cluster/addons)
? ? # If you are NOT using this as an addon, you should comment out this line.
? ? kubernetes.io/cluster-service: 'true'
? ? kubernetes.io/name: Heapster
? name: heapster
? namespace: kube-system
spec:
? ports:
? - port: 80
? ? targetPort: 8082
? selector:
? ? k8s-app: heapster
kubectl apply -f?heapster.yaml
部署heapster數(shù)據(jù)庫influxdb.yaml
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
? name: monitoring-influxdb
? namespace: kube-system
spec:
? replicas: 1
? template:
? ? metadata:
? ? ? labels:
? ? ? ? task: monitoring
? ? ? ? k8s-app: influxdb
? ? spec:
? ? ? containers:
? ? ? - name: influxdb
? ? ? ? image: 192.168.220.84/third_party/heapster-influxdb-amd64:v1.1.1
? ? ? ? volumeMounts:
? ? ? ? - mountPath: /data
? ? ? ? ? name: influxdb-storage
? ? ? volumes:
? ? ? - name: influxdb-storage
? ? ? ? emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
? labels:
? ? task: monitoring
? ? # For use as a Cluster add-on (https://github.com/kubernetes/kubernetes/tree/master/cluster/addons)
? ? # If you are NOT using this as an addon, you should comment out this line.
? ? kubernetes.io/cluster-service: 'true'
? ? kubernetes.io/name: monitoring-influxdb
? name: monitoring-influxdb
? namespace: kube-system
spec:
? ports:
? - port: 8086
? ? targetPort: 8086
? selector:
? ? k8s-app: influxdb
kubectl apply -f?influxdb.yaml
當然里面所用到的鏡像全部是我自己搭建的私服鏡像倉庫墓臭,大家可以自己按需求搭建蘸鲸,教程就不給了,參考https://blog.csdn.net/u012979009/article/details/70860107窿锉。
鏡像和安裝包在最后會附上下載地址酌摇。膝舅。。
如果heapster監(jiān)控圖標沒有出來窑多,可以嘗試刪除kubernetes-dashboard pod铸史,然后等它自動重新部署,若還是無法展示怯伊,也可以通過kubectl logs podname的形式來查看日志琳轿。
認證和授權(quán)
部署了k8s的控制面板,并不是誰都可以訪問誰都可以操作的耿芹,k8s的控制面板默認驗證方式有kubeconfig和token崭篡,但是都比較難懂
這里我們使用basicauth的方式進行apiserver的驗證
vim /etc/kubernetes/manifests/pki/basic-auth-file 用于存放用戶名和密碼
格式是密碼,用戶名吧秕,用戶id
類似下面的例子
admin123,test,1
12345,admin,2
然后給kube-apiserver添加basic_auth驗證
vim?/etc/kubernetes/manifests/kube-apiserver.yaml
- command:
- --basic-auth-file=/etc/kubernetes/pki/basic-auth-file
保存琉闪。
注意,保存后apiserver會重新啟動砸彬,不知道是bug還是什么我的機器在保存第一次的時候會存在apiserver無法啟動的問題颠毙,必須再打開kube-apiserver.yaml一次再執(zhí)行一次保存才能重啟apiserver。
由于使用的是1.10版本砂碉,k8s1.6后版本都采用RBAC授權(quán)模型蛀蜜,我們還得給用戶一些權(quán)限
在k8s里有一個宇宙無敵大的權(quán)限clusterrole?cluster-admin,我們把這個權(quán)限附給我們的管理員用戶
kubectl?create?clusterrolebinding login-on-dashboard-with-cluster-admin --clusterrole=cluster-admin --user=test
同時增蹭,如果你不想讓用戶沒有那么大的權(quán)限滴某,也可以自定義。對于授權(quán)認證方面我會在別的文章里再詳細說滋迈。
設(shè)置完成后通過火狐瀏覽器(其他瀏覽器不一定行)訪問https://ip:31234即可看到頁面
輸入用戶名密碼即可看到控制面板
這樣簡單的kubernetes集群就搭建完成了霎奢。
完全參考了kubernetes1.9離線部署,并做了自己實踐的一些補充
密碼:mdn6