查看原文
其他

kubeadm部署kubernetes 1.18集群

木讷大叔爱运维 木讷大叔爱运维 2022-07-13



Kubeadm 是一个工具,它提供了 kubeadm init 以及 kubeadm join 这两个命令作为快速创建 kubernetes 集群的最佳实践。

kubeadm 通过执行必要的操作来启动和运行一个最小可用的集群。它被故意设计为只关心启动集群,而不是之前的节点准备工作。

kubeadm部署原理

kubeadm 部署k8s集群,主要为以下两步:

# 创建一个 Master 节点$ kubeadm init
# 将一个 Node 节点加入到当前集群中$ kubeadm join <Master节点的IP和端口 >

kubeadm init阶段:

  1. 自动化的集群机器合规检查;

  2. 自动化生成集群运行所需的各类证书及各类配置,并将Master节点信息保存在名为cluster-info的ConfigMap中;

  3. 通过static Pod方式,运行API server, controller manager 、scheduler及etcd组件;

  4. 生成Token以便其他节点加入集群;

kubeadm join阶段:

  1. 节点通过token访问kube-apiserver,获取cluster-info中信息,主要是apiserver的授权信息(节点信任集群);

  2. 通过授权信息,kubelet可执行TLS bootstrapping,与apiserver真正建立互信任关系(集群信任节点);


因此kubeadm做的事就是把大部分组件都容器化,通过StaticPod方式运行,并自动化了大部分的集群配置及认证等工作,通过简单几步即可搭建一个可用Kubernetes的集群。


环境准备

IP
主机名
角色
操作系统
192.168.3.217master
master
Centos7
192.168.3.218node1
workCentos7
192.168.3.219node2
work
Centos7

kubernetes 版本为1.18.2

部署

一、docker环境部署

docker环境需要在3个节点全部安装

1.安装docker ce

# step 1: 安装必要的一些系统工具sudo yum install -y yum-utils device-mapper-persistent-data lvm2# Step 2: 添加软件源信息sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo# Step 3: 更新并安装 Docker-CEsudo yum makecache fastsudo yum -y install docker-ce# Step 4: 开启Docker服务sudo service docker start

2.安装阿里云镜像加速器

#针对Docker客户端版本大于 1.10.0 的用户#通过修改daemon配置文件/etc/docker/daemon.json来使用加速器sudo mkdir -p /etc/dockersudo tee /etc/docker/daemon.json <<-'EOF'{"registry-mirrors": ["https://xxxxxx.mirror.aliyuncs.com"]}EOFsudo systemctl daemon-reloadsudo systemctl restart docker

3.安装docker-compose

curl -L "https://github.com/docker/compose/releases/download/1.25.4/docker-compose-$(uname -s)-$(uname -m)" -o /bin/docker-compose


二、k8s部署


1.系统初始化

kuadm init 阶段,需要进行集群机器的合规检查,请参见Centos7初始化适合k8s运行的系统环境

通过初始化,即可通过服务器的合规检查。

# 全部节点192.168.3.217 master192.168.3.218 node1192.168.3.219 node2

2.安装kubelet、kubeadm、kubectl

# 所有节点# 添加阿里kubernetes源cat <<EOF > /etc/yum.repos.d/kubernetes.repo[kubernetes]name=Kubernetesbaseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/enabled=1gpgcheck=1repo_gpgcheck=1gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpgEOF
# 安装kubelet、kubeadm、kubectlyum install -y kubelet kubeadm kubectlsystemctl enable kubelet && systemctl start kubelet

其中:

  1. kubeadm:初始化集群;

  2. kubelet:运行在集群中的所有node节点上,负责启动pod和容器;

  3. kubectl:k8s命令行工具,运行在master节点上,通过kubectl可以部署和管理应用,查看各种资源、创建、删除、更新各种组件;


3.初始化集群

初始化集群可以通过yaml配置文件和命令行直接初始化,在此我们都来介绍下。

(1)命令行直接初始化

# master节点kubeadm init --kubernetes-version=1.18.2 --apiserver-advertise-address=192.168.3.217 --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers --service-cidr=10.1.0.0/16 --pod-network-cidr=10.244.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/.kubesudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo 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.3.217:6443 --token 8nfcuq.joeuirw95y0fi8ga \--discovery-token-ca-cert-hash sha256:b53601e735acdb21622e6117ea19077b87825c42cd1eaaf30e1df7b83b7b3bd8

其中:

  1. --kubernetes-version  指定kubernetes版本

  2. --apiserver-advertise-address  API 服务器所公布的其正在监听的 IP 地址。如果未设置,则使用默认网络接口。

  3. --image-repository 选择用于拉取镜像的容器仓库

  4. --service-cidr service的虚拟 IP 地址,(默认“10.96.0.0/12”)

  5. --pod-network-cidr 指明 pod 网络可以使用的 IP 地址段。如果设置了这个参数,控制平面将会为每一个节点自动分配 CIDRs。

  6. --ignore-preflight-errors 将错误显示为警告的检查列表进行忽略


注意:

  1. 由于kubeadm 默认从官网k8s.grc.io下载所需镜像,国内无法访问,需要通过--image-repository指定仓库,在此我们使用"registry.cn-hangzhou.aliyuncs.com/google_containers"。

  2. init打印信息,给了我们下一步的提示,即部署pod网络、将work节点加入集群。


(2)yaml初始化

# master节点# 1.生成 init 配置文件kubeadm config print init-defaults > kubeadmin-config.yamlW0605 14:37:18.548586 7592 configset.go:202] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io] # 2.编辑 yaml 配置文件vim kubeadmin-config.yamlapiVersion: kubeadm.k8s.io/v1beta2bootstrapTokens:- groups:- system:bootstrappers:kubeadm:default-node-tokentoken: abcdef.0123456789abcdefttl: 24h0m0susages:- signing- authenticationkind: InitConfigurationlocalAPIEndpoint:# 需修改当前节点的宿主机地址advertiseAddress: 192.168.3.217bindPort: 6443nodeRegistration:criSocket: /var/run/dockershim.sockname: node1taints:- effect: NoSchedulekey: node-role.kubernetes.io/master---apiServer:timeoutForControlPlane: 4m0sapiVersion: kubeadm.k8s.io/v1beta2certificatesDir: /etc/kubernetes/pkiclusterName: kubernetescontrollerManager: {}dns:type: CoreDNSetcd:local:dataDir: /var/lib/etcd# 镜像仓库imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containerskind: ClusterConfiguration# 版本更改为当前版本kubernetesVersion: v1.18.2networking:dnsDomain: cluster.local# pod的地址,注意此地址需要和网络插件flannel或其他插件的默认地址保持一致,此处为10.244.0.0podSubnet: 10.244.0.0/16# service的地址serviceSubnet: 10.96.0.0/12scheduler: {}
# 将调度模式由默认的iptables改为ipvs---apiVersion: kubeproxy.config.k8s.io/v1alpha1kind: KubeProxyConfigurationfeatureGates:SupportIPVSProxyMode: truemode: ipvs
# 3. 初始化kubeadm init --config=kubeadm-config.yaml | tee kubeadm-init.log

集群初始化可以按需选择其中一种方式,不过yaml配置文件便于我们日后查看。


注意:

初始化我们使用ipvs调度,如果系统中没有安装ipvs,则会退化为iptables。


4.配置kubectl

kubeadm init 完成初始化后,会打印信息,指示我们如何配置kubectl。

# master节点echo $HOMEmkdir -p $HOME/.kubecp -i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config


5.部署pod网络

如果没有pod网络,那么pod之前无法通信。kubeadm工具安装只支持CNI(Container Network Interface)网络插件,因此需要安装相应插件(例如Flannel、Calico、Romana、Weave-net等插件),我们使用Overlay网络的Flannel插件。

# master节点kubectl apply -f https://gitlab.abcxlab.com/bootcamp/k8s-quick-start/-/raw/master/k8s/1.0_kube-flannel.yaml
podsecuritypolicy.policy/psp.flannel.unprivileged createdclusterrole.rbac.authorization.k8s.io/flannel createdclusterrolebinding.rbac.authorization.k8s.io/flannel createdserviceaccount/flannel createdconfigmap/kube-flannel-cfg createddaemonset.apps/kube-flannel-ds-amd64 createddaemonset.apps/kube-flannel-ds-arm64 createddaemonset.apps/kube-flannel-ds-arm createddaemonset.apps/kube-flannel-ds-ppc64le createddaemonset.apps/kube-flannel-ds-s390x created
# 查看状态kubectl get pod -n kube-system# flannel 相关podkube-flannel-ds-amd64-5gfwh 1/1 Running 1 25dkube-flannel-ds-amd64-js877 1/1 Running 1 25dkube-flannel-ds-amd64-pb4d7 1/1 Running 1 25

注意:

  1. k8s的namespace 分为default和kube-system,默认使用default。而k8s的系统组件core-dns、etcd、kube-flannel、kube-proxy、scheduler等都在kube-system中。

  2. 如果有多个网卡,可以通过--iface=eth0指定网卡,防止DNS无法解释;


6.加入kuburnetes集群

# work 节点kubeadm join 192.168.3.217:6443 --token 8nfcuq.joeuirw95y0fi8ga --discovery-token-ca-cert-hash sha256:b53601e735acdb21622e6117ea19077b87825c42cd1eaaf30e1df7b83b7b3bd8W0522 11:39:24.304798 7867 join.go:346] [preflight] WARNING: JoinControlPane.controlPlane settings will be ignored when control-plane flag is not set.[preflight] Running pre-flight checks[preflight] Reading configuration from the cluster...[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'[kubelet-start] Downloading configuration for the kubelet from the "kubelet-config-1.18" ConfigMap in the kube-system namespace[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"[kubelet-start] Starting the kubelet[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...
This node has joined the cluster:* Certificate signing request was sent to apiserver and a response was received.* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
# 查看集群状态kubectl get nodesNAME STATUS ROLES AGE VERSIONmaster Ready master 25d v1.18.2node1          Ready    <none>   25d   v1.18.2node2          Ready    <none>   25d   v1.18.2
# 组件状态# 节点信息kubectl get csNAME STATUS MESSAGE ERRORcontroller-manager Healthy ok scheduler Healthy ok etcd-0 Healthy {"health":"true"}
# 集群信息kubectl cluster-infoKubernetes master is running at https://192.168.3.217:6443KubeDNS is running at https://192.168.3.217:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxyMetrics-server is running at https://192.168.3.217:6443/api/v1/namespaces/kube-system/services/https:metrics-server:/proxy

至此,我们的三节点的集群部署就完成了。


实例

k8s部署一个服务的流程大体是:

  1. 工作负载(ReplicaSet/Deploymnt/DaemonSet/StatefulSet/Job/CronJob)

    不同的工作负载对应不同的服务,如nginx、mysql、计划任务等

  2. Service(Cluster/NodePort/LoadBalance/Ingress)

        不同的Service对应不同的服务暴露访问方式,如集群内部访问、对外访问、4层访问还是7层访问。


下面我们将部署一个Nginx服务,并展示Server的服务访问方式。


1.部署Deployment

Nginx是一个无状态服务,因此我们使用Deployment类型的工作负载。

vim nginx-deployment.yaml# nginx资源清单apiVersion: apps/v1kind: Deploymentmetadata: # pod名称 name: nginx-deploymentspec:  # 副本数量 replicas: 3 selector: matchLabels:      #匹配标签 app: nginx template: metadata: labels:        # 自定义标签,需与上面一致 app: nginx spec: containers: # 镜像名 - name: nginx        # 镜像tag image: nginx:1.7.9        # 拉取策略,如果本地没有则从远程仓库拉取 imagePullPolicy: IfNotPresent        # master节点执行命令# 部署kubectl apply -f nginx-deployment.yaml
#查看pod信息kubectl get pod -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESnginx-deployment-6dd8bc586b-tgsbj     1/1     Running   0          21h     10.244.1.36   node1     <none>           <none>nginx-deployment-6dd8bc586b-tssbj     1/1     Running   0          21h     10.244.1.37   node1          <none>           <none>nginx-deployment-6dd8bc586b-tgsbj     1/1     Running   0          21h     10.244.2.38   node2          <none>           <none>
#访问任意一个pod ipcurl 10.244.1.36curl 10.244.1.37curl 10.244.2.36

此时创建完成的pod只能通过pod ip进行访问,但是此pod ip不是固定的,随着pod的创建,pod ip会变化。但是我们可以通过Service提供的访问方式来绑定pod。


2.部署Serveice

vim nginx-service.yamlapiVersion: v1kind: Servicemetadata: # svc名称 name: nginx-servicespec: #类型,可以为NodePort、LoadBalance type: ClusterIP selector:    # 通过标签绑定pod app: nginx ports: - name: http      # 对外暴露端口 port: 80 # pod端口 targetPort: 80 # 部署kubectl apply -f nginx-service.yaml
#查看kubectl get svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEkubernetes ClusterIP 10.1.0.1 <none> 443/TCP 25dnginx-service        ClusterIP   10.1.133.58   <none>        80/TCP         5d19hnginx-service-test NodePort 10.1.71.52 <none> 80:30191/TCP 45h
#访问# ClusterIP方式curl 10.1.133.58
# NodePort方式curl 192.168.3.217:30191curl 192.168.3.218:30191curl 192.168.3.219:30191


但是此时kubernetes集群通过Service提供的ClusterIP访问方式只能集群内部使用,而NodePort、LoadeBalance对外访问方式属于4层TCP。如果我们想使用基于固定IP的代理多个HTTP/HTTPS服务,例如nginx,此时我们需要进一步部署ingress-nginx。

Ingress-nginx部署

#1.安装wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-0.32.0/deploy/static/provider/baremetal/deploy.yaml# 部署kubectl apply -f deploy.yaml#查看kubectl get pod -n ingress-nginxkubectl get svc -n ingress-nginx
#2.部署nginx deployment和nginx servicevim nginx-deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata: name: nginx-deploymentspec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.7.9 imagePullPolicy: IfNotPresent---apiVersion: v1kind: Servicemetadata: name: nginx-servicespec: type: ClusterIP selector: app: nginx ports: - name: http port: 80 targetPort: 80
kubectl apply -f nginx-deployment.yaml
#3.部署nginx ingressvim nginx-ingress.yamlapiVersion: networking.k8s.io/v1beta1kind: Ingressmetadata: name: ingress-nginxspec: rules: - host: www.test1.com http: paths: - path: / backend: serviceName: nginx-service servicePort: 80
kubectl apply -f nginx-ingress.yaml
[root@uvmsvr-3-217 k8s]# kubectl get svc -n ingress-nginxNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEingress-nginx-controller NodePort 10.1.39.222 <none> 80:30570/TCP,443:30832/TCP 21hingress-nginx-controller-admission ClusterIP 10.1.254.169 <none> 443/TCP 21h
#测试,通过域名访问curl -x 192.168.3.217:30570 www.test1.comcurl -x 192.168.3.218:30570 www.test1.comcurl -x 192.168.3.219:30570 www.test1.com


总结

k8s的知识点非常多,通过对其部署能够帮助我们更好的了解k8s的组成及运行。我们需要通过实践去深入体会k8s给我们的运维过程带来的更多可能性。





关注我们




您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存