K8S部署和基础组件的理解整合(一)

一.Pod

K8S下可以有很多Pod,每个Pods都有一个或多个容器,是容器的集合。是K8S下最小的对象,Pods可以命名。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bW0PcB5O-1628524532764)(E:\Makedown-Documentation-Typora\images\image-20210717174037533.png)]

二.Label

#例如一些Jobs、Deployments 这些对象想要选我们的数据库Pods就可以用到 labes了。

LabeI是识别Kubernetes对象的标签,以key/value的方式附加到对象上( key最长不能超过63字节,value可以为空,也可以是不超过253字节的字符串)。
Label不提供唯一性,并且实际上经常是很多对象(如Pods )都使用相同的label来标志具体的应用。
Label定义好后其他对象可以使用Label 5elector来选择- -组相同label的对象 (比如Service用label来选择-组Pod )。Label Selector支持以下几种方式:
●等式,如app=nginx和env!=production
●集合,如env in (production, qa)
●多个label (它们之间是AND关系) ,如app=nginx,env=test

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RMdlzhPc-1628524532772)(E:\Makedown-Documentation-Typora\images\image-20210717173906018.png)]

标签其实就一对 key/value ,被关联到对象上,比如Pod,标签的使用我们倾向于能够标示对象的特殊特点,并且对用户而言是有意义的(就是一眼就看出了这个Pod是尼玛数据库)。我们最终会索引并且反向索引(reverse-index)labels,以获得更高效的查询和监视,把他们用到UI或者CLI中用来排序或者分组等等。我们不想用那些不具有指认效果的label来污染label,特别是那些体积较大和结构型的的数据。不具有指认效果的信息应该使用Annotation来记录。

三.Namespace

不同Namespace起到隔离作用。Namespace用于Pod之间区分开发环境、测试环境、生产环境等。不同Namespace下可以有完全同名字的Label标识。

四.Deployments

是否手动创建Pod ,如果想要创建同一个容器的多份拷贝, 需要一个个分别创建出来么 ,能否将Pods划到逻辑
组里?

Deployment确保任意时间都有指定数量的Pod“副本” 在运行。如果为某个Pod创建了Deployment并且指定
3个副本,它会创建3个Pod ,并且持续监控它们。如果某个Pod不响应,那么Deployment会替换它,保持总
数为3.

如果之前不响应的Pod恢复了,现在就有4个Pod了,那么Deployment会将其中一个终止保持总数为3。如果
在运行中将副本总数改为5 , Deployment会立刻启动2个新Pod ,保证总数为5. Deployment还支持回滚和滚
动升级。
当创建Deployment时,需要指定两个东西:
●Pod模板 :用来创建Pod副本的模板
●Label标签 : Deployment需要监控的Pod的标签。

现在已经创建了Pod的一些副本,那么在这些副本上如何均衡负载呢?我们需要的是Service。

五.services

Service是应用服务的抽象,通过labels为应用提供负载均衡和服务发现。匹配labels的Pod IP和
端口列表组成endpoints ,由kube proxy负责将服务IP负载均衡到这些endpoints上。
每个Service都会自动分配一个cluster IP (仅在集群内部可访问的虚拟地址)和DNS名,其他容
器可以通过该地址或DNS来访问服务,而不需要了解后端容器的运行。

5.1 endpoint

例如,k8s集群中创建一个名为hello的service,就会生成一个同名的endpoint对象,endpoints就是service关联的pod的ip地址和端口。

endpoint是k8s集群中的一个资源对象,存储在etcd中,用来记录一个service对应的所有pod的访问地址。service配置selector,endpoint controller才会自动创建对应的endpoint对象;否则,不会生成endpoint对象。

一个 Service 由一组 backend Pod 组成。这些 Pod 通过 endpoints 暴露出来。 Service Selector 将持续评估,结果被 POST 到一个名称为 Service-hello 的 Endpoint 对象上。 当 Pod 终止后,它会自动从 Endpoint 中移除,新的能够匹配上 Service Selector 的 Pod 将自动地被添加到 Endpoint 中。 检查该 Endpoint,注意到 IP 地址与创建的 Pod 是相同的。现在,能够从集群中任意节点上使用 curl 命令请求 hello Service : 。 注意 Service IP 完全是虚拟的,它从来没有走过网络,如果对它如何工作的原理感到好奇,可以阅读更多关于 服务代理 的内容。

Endpoints是实现实际服务的端点集合。

基本概念与组件

Kubernetes中的绝大部分概念都抽象成Kubernetes管理的一种资源对象,下面我们一起复习一
下我们上节课遇到的一些资源对象:
r
●Master : Master节点是Kubernetes集群的控制节点,负责整个集群的管理和控制。Master
节点_上包含以下组件:
。kube apiserver :集群控制的入口, 提供HTTP REST服务
。kube-controller-manager : Kubernetes集群中所有资源对象的自动化控制中心
。kube-scheduler :负责Pod的调度
●Node : Node节点是Kubernetes集群中的工作节点, Node.上的工作负载由Master节点分
配,工作负载主要是运行容器应用。Node节点上包含以下组件:
。kubelet :负责Pod的创建、启动、监控、重启、销毁等工作,同时与Master节点协作,实
现集群管理的基本功能。
。kube-proxy :实现Kubernetes Service的通信和负载均衡
。运行容器化(Pod)应用
●Pod: Pod是Kubernetes最基本的部署调度单元。每个Pod可以由一个或多个业务容器和一个
根容器(Pause容器)组成。一个Pod表示某 个应用的一个实例
●ReplicaSet :是Pod副本的抽象,用于解决Pod的扩容和伸缩
●Deployment : Deployment表示部署,在内部使用ReplicaSet来实现。可以通过
Deployment来生成相应的ReplicaSet完成Pod副本的创建
●Service : Service是Kubernetes最重要的资源对象。Kubernetes中的Service对象可以对应
微服务架构中的微服务。Service定义了服务的访问入口,服务的调用者通过这个地址访问
Service后端的Pod副本实例。Service通过Label Selector同后端的Pod副本建立关系,
Deployment保证后端Pod副本的数量,也就是保证服务的伸缩性。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1IOkE6sB-1628524532774)(E:\Makedown-Documentation-Typora\images\image-20210718130909577.png)]

●用户通过REST API创建一个Pod
●apiserver将其写入etcd
●scheduluer检测到未绑定Node的Pod ,开始调度并更新Pod的Node绑定
●kubelet检测到有新的Pod调度过来,通过container runtime运行该Pod
●kubelet 通过container runtime取到Pod状态,并更新到apiserver中

----------kubeadm安装----------

#在每个节点上添加 hosts 信息:
$ vim /etc/hosts
192.168.31.40 master1
192.168.31.154 node1
192.168.31.21 node2
#禁用防火墙:
systemctl stop firewalld
systemctl disable firewalld
cat /etc/selinux/config
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
#由于开启内核 ipv4 转发需要加载 br_netfilter 模块,所以加载下该模块:
modprobe br_netfilter
echo "net.bridge.bridge-nf-call-ip6tables = 1"  >>/etc/sysctl.d/k8s.conf
echo "net.bridge.bridge-nf-call-iptables = 1" >>/etc/sysctl.d/k8s.conf
echo "net.ipv4.ip_forward = 1" >>/etc/sysctl.d/k8s.conf
#关闭 swap 分区:
swapoff -a
vim /etc/fstab
```(加#注释掉)
UUID=48f429fc-2abd-4283-905a-982d8bf56452 swap                    swap    defaults        0 0
```
#修改/etc/fstab文件,注释掉 SWAP 的自动挂载,使用free -m确认 swap 已经关闭。swappiness 参数调整,修改/etc/sysctl.d/k8s.conf添加下面一行:
echo "vm.swappiness=0" >> /etc/sysctl.d/k8s.conf
sysctl -p /etc/sysctl.d/k8s.conf
#安装 ipvs:
cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF
chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4
#上面脚本创建了的/etc/sysconfig/modules/ipvs.modules文件,保证在节点重启后能自动加载所需模块。使用lsmod | grep -e ip_vs -e nf_conntrack_ipv4命令查看是否已经正确加载所需的内核模块。

#接下来还需要确保各个节点上已经安装了 ipset 软件包:
yum install ipset
#为了便于查看 ipvs 的代理规则,最好安装一下管理工具 ipvsadm:
yum install ipvsadm -y
#同步服务器时间
yum install chrony -y
systemctl enable chronyd
systemctl start chronyd
chronyc sources
210 Number of sources = 4
MS Name/IP address         Stratum Poll Reach LastRx Last sample
===============================================================================
^+ sv1.ggsrv.de                  2   6    17    32   -823us[-1128us] +/-   98ms
^- montreal.ca.logiplex.net      2   6    17    32    -17ms[  -17ms] +/-  179ms
^- ntp6.flashdance.cx            2   6    17    32    -32ms[  -32ms] +/-  161ms
^* 119.28.183.184                2   6    33    32   +661us[ +357us] +/-   38ms
$ date
Tue Aug 27 09:28:41 CST 2019
#安装docker
yum install -y yum-utilsdevice-mapper-persistent-data lvm2 yum-utils
#yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum list docker-ce --showduplicates | sort -r
yum install -y docker-ce-19.03.11

#启动docker
$ systemctl start docker
$ systemctl enable docker
cat <<EOF > /etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2",
  "registry-mirrors" : [
    "https://ot2k4d59.mirror.aliyuncs.com/"
  ]
}
EOF
$ systemctl restart docker
#安装kubeadm、kubelet、kubectl
#google
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg
        https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF
#阿里云
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

#然后安装 kubeadm、kubelet、kubectl:
# --disableexcludes 禁掉除了kubernetes之外的别的仓库
yum install -y kubelet-1.19.3 kubeadm-1.19.3 kubectl-1.19.3 --disableexcludes=kubernetes
#kubelet开机启动
systemctl enable --now kubelet
kubeadm version (查询版本号)
kubeadm version: &version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.3", GitCommit:"1e11e4a2108024935ecfcb2912226cedeafd99df", GitTreeState:"clean", BuildDate:"2020-10-14T12:47:53Z", GoVersion:"go1.15.2", Compiler:"gc", Platform:"linux/amd64"}

初始化集群

然后接下来在 master 节点配置 kubeadm 初始化文件,可以通过如下命令导出默认的初始化配置:

$ kubeadm config print init-defaults > kubeadm.yaml

然后根据我们自己的需求修改配置,比如修改 imageRepository 的值,kube-proxy 的模式为 ipvs,另外需要注意的是我们这里是准备安装 flannel 网络插件的,需要将 networking.podSubnet 设置为10.244.0.0/16

apiVersion: kubeadm.k8s.io/v1beta2bootstrapTokens:- groups:  - system:bootstrappers:kubeadm:default-node-token  token: abcdef.0123456789abcdef  ttl: 24h0m0s  usages:  - signing  - authenticationkind: InitConfigurationlocalAPIEndpoint:  advertiseAddress: 192.168.31.40  # apiserver 节点内网IP  bindPort: 6443nodeRegistration:  criSocket: /var/run/dockershim.sock  name: master1  taints:  - effect: NoSchedule    key: node-role.kubernetes.io/master---apiServer:  timeoutForControlPlane: 4m0sapiVersion: kubeadm.k8s.io/v1beta2certificatesDir: /etc/kubernetes/pkiclusterName: kubernetescontrollerManager: {}dns:  type: CoreDNSetcd:  local:    dataDir: /var/lib/etcdimageRepository: registry.aliyuncs.com/google_containers# registry.aliyuncs.com/k8sxio   # 修改成阿里云镜像源kind: ClusterConfigurationkubernetesVersion: v1.19.3networking:  dnsDomain: cluster.local  podSubnet: 10.244.0.0/16  # Pod 网段,flannel插件需要使用这个网段  serviceSubnet: 10.96.0.0/12scheduler: {}---apiVersion: kubeproxy.config.k8s.io/v1alpha1kind: KubeProxyConfigurationmode: ipvs  # kube-proxy 模式

配置提示

对于上面的资源清单的文档比较杂,要想完整了解上面的资源对象对应的属性,可以查看对应的 godoc 文档,地址: https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2。

然后使用上面的配置文件进行初始化:

# 也可以提前先将相关镜像 pull 下来# kubeadm config images pull --config kubeadm.yaml$ kubeadm init --config kubeadm.yamlW1017 17:52:13.831477    8682 configset.go:348] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io][init] Using Kubernetes version: v1.19.3[preflight] Running pre-flight checks[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'[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 [kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local master1] and IPs [10.96.0.1 10.151.30.11][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 [localhost master1] and IPs [10.151.30.11 127.0.0.1 ::1][certs] Generating "etcd/peer" certificate and key[certs] etcd/peer serving cert is signed for DNS names [localhost master1] and IPs [10.151.30.11 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[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[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"[control-plane] Creating static Pod manifest for "kube-scheduler"[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.507850 seconds[upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace[kubelet] Creating a ConfigMap "kubelet-config-1.19" 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 master1 as control-plane by adding the label "node-role.kubernetes.io/master=''"[mark-control-plane] Marking the node master1 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-proxyYour 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/configYou 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.31.40:6443 --token abcdef.0123456789abcdef \    --discovery-token-ca-cert-hash sha256:570e650eb241640ae0cdb0e1c4dd38cfac84b3c38a50d812cfddbb885ee10efa 
#将 master 节点上面的 $HOME/.kube/config 拷贝到所有master和node中mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/config

添加节点

记住初始化集群上面的配置和操作要提前做好,将 master 节点上面的 $HOME/.kube/config 文件拷贝到 node 节点对应的文件中,安装 kubeadm、kubelet、kubectl(可选),然后执行上面初始化完成后提示的 join 命令即可:

$ kubeadm join 10.151.30.11:6443 --token abcdef.0123456789abcdef \>     --discovery-token-ca-cert-hash sha256:da20ca0b12aea4afedc2a05026c285668ac3403949a5d091aa3123a7e87b9913[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] 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.

join 命令

如果忘记了上面的 join 命令可以使用命令 kubeadm token create --print-join-command 重新获取。

kubeadm init 命令执行流程如下图所示:

kubeadm init

执行成功后运行 get nodes 命令:

$ kubectl get nodesNAME          STATUS     ROLES    AGE    VERSIONydzs-master   NotReady      master   39m    v1.15.3ydzs-node1    NotReady   <none>   106s   v1.15.3

可以看到是 NotReady 状态,这是因为还没有安装网络插件,接下来安装网络插件,可以在文档 https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/ 中选择我们自己的网络插件,这里我们安装 flannel:

Flannel网络插件安装

$ wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml# 因为有节点是多网卡,所以需要在资源清单文件中指定内网网卡# 搜索到名为 kube-flannel-ds 的 DaemonSet,在kube-flannel容器下面$ vi kube-flannel.yml---apiVersion: policy/v1beta1kind: PodSecurityPolicymetadata:  name: psp.flannel.unprivileged  annotations:    seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default    seccomp.security.alpha.kubernetes.io/defaultProfileName: docker/default    apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default    apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/defaultspec:  privileged: false  volumes:  - configMap  - secret  - emptyDir  - hostPath  allowedHostPaths:  - pathPrefix: "/etc/cni/net.d"  - pathPrefix: "/etc/kube-flannel"  - pathPrefix: "/run/flannel"  readOnlyRootFilesystem: false  # Users and groups  runAsUser:    rule: RunAsAny  supplementalGroups:    rule: RunAsAny  fsGroup:    rule: RunAsAny  # Privilege Escalation  allowPrivilegeEscalation: false  defaultAllowPrivilegeEscalation: false  # Capabilities  allowedCapabilities: ['NET_ADMIN', 'NET_RAW']  defaultAddCapabilities: []  requiredDropCapabilities: []  # Host namespaces  hostPID: false  hostIPC: false  hostNetwork: true  hostPorts:  - min: 0    max: 65535  # SELinux  seLinux:    # SELinux is unused in CaaSP    rule: 'RunAsAny'---kind: ClusterRoleapiVersion: rbac.authorization.k8s.io/v1metadata:  name: flannelrules:- apiGroups: ['extensions']  resources: ['podsecuritypolicies']  verbs: ['use']  resourceNames: ['psp.flannel.unprivileged']- apiGroups:  - ""  resources:  - pods  verbs:  - get- apiGroups:  - ""  resources:  - nodes  verbs:  - list  - watch- apiGroups:  - ""  resources:  - nodes/status  verbs:  - patch---kind: ClusterRoleBindingapiVersion: rbac.authorization.k8s.io/v1metadata:  name: flannelroleRef:  apiGroup: rbac.authorization.k8s.io  kind: ClusterRole  name: flannelsubjects:- kind: ServiceAccount  name: flannel  namespace: kube-system---apiVersion: v1kind: ServiceAccountmetadata:  name: flannel  namespace: kube-system---kind: ConfigMapapiVersion: v1metadata:  name: kube-flannel-cfg  namespace: kube-system  labels:    tier: node    app: flanneldata:  cni-conf.json: |    {      "name": "cbr0",      "cniVersion": "0.3.1",      "plugins": [        {          "type": "flannel",          "delegate": {            "hairpinMode": true,            "isDefaultGateway": true          }        },        {          "type": "portmap",          "capabilities": {            "portMappings": true          }        }      ]    }  net-conf.json: |    {      "Network": "10.244.0.0/16",      "Backend": {        "Type": "vxlan"      }    }---apiVersion: apps/v1kind: DaemonSetmetadata:  name: kube-flannel-ds  namespace: kube-system  labels:    tier: node    app: flannelspec:  selector:    matchLabels:      app: flannel  template:    metadata:      labels:        tier: node        app: flannel    spec:      affinity:        nodeAffinity:          requiredDuringSchedulingIgnoredDuringExecution:            nodeSelectorTerms:            - matchExpressions:              - key: kubernetes.io/os                operator: In                values:                - linux      hostNetwork: true      priorityClassName: system-node-critical      tolerations:      - operator: Exists        effect: NoSchedule      serviceAccountName: flannel      initContainers:      - name: install-cni        image: quay.io/coreos/flannel:v0.14.0        command:        - cp        args:        - -f        - /etc/kube-flannel/cni-conf.json        - /etc/cni/net.d/10-flannel.conflist        volumeMounts:        - name: cni          mountPath: /etc/cni/net.d        - name: flannel-cfg          mountPath: /etc/kube-flannel/      containers:      - name: kube-flannel        image: quay.io/coreos/flannel:v0.14.0        command:        - /opt/bin/flanneld        args:        - --ip-masq        - --kube-subnet-mgr        resources:          requests:            cpu: "100m"            memory: "50Mi"          limits:            cpu: "100m"            memory: "50Mi"        securityContext:          privileged: false          capabilities:            add: ["NET_ADMIN", "NET_RAW"]        env:        - name: POD_NAME          valueFrom:            fieldRef:              fieldPath: metadata.name        - name: POD_NAMESPACE          valueFrom:            fieldRef:              fieldPath: metadata.namespace        volumeMounts:        - name: run          mountPath: /run/flannel        - name: flannel-cfg          mountPath: /etc/kube-flannel/      volumes:      - name: run        hostPath:          path: /run/flannel      - name: cni        hostPath:          path: /etc/cni/net.d      - name: flannel-cfg        configMap:          name: kube-flannel-cfg$ kubectl apply -f kube-flannel.yml  # 安装 flannel 网络插件

隔一会儿查看 Pod 运行状态:

$ kubectl get pods -n kube-systemNAME                              READY   STATUS     RESTARTS   AGEcoredns-6d56c8448f-plwrw          1/1     Running    0          4m5scoredns-6d56c8448f-s46mp          1/1     Running    0          4m5setcd-master1                      1/1     Running    0          4m13skube-apiserver-master1            1/1     Running    0          4m13skube-controller-manager-master1   1/1     Running    0          4m13skube-flannel-ds-6tv9h             1/1     Running    0          50skube-flannel-ds-t6m2x             1/1     Running    0          50skube-proxy-bcdv5                  1/1     Running    0          4m5skube-proxy-fmhs7                  1/1     Running    0          2m43skube-scheduler-master1            1/1     Running    0          4m13s

Flannel 网络插件

当我们部署完网络插件后执行 ifconfig 命令,正常会看到新增的cni0flannel1这两个虚拟设备,但是如果没有看到cni0这个设备也不用太担心,我们可以观察/var/lib/cni目录是否存在,如果不存在并不是说部署有问题,而是该节点上暂时还没有应用运行,我们只需要在该节点上运行一个 Pod 就可以看到该目录会被创建,并且cni0设备也会被创建出来。

网络插件运行成功了,node 状态也正常了:

$ kubectl get nodesNAME      STATUS   ROLES    AGE     VERSIONmaster1   Ready    master   5m7s    v1.19.3node1     Ready    <none>   3m23s   v1.19.3

用同样的方法添加另外一个节点即可。

Dashboard安装

v1.19.3 版本的集群需要安装最新的 2.0+ 版本的 Dashboard:

# 推荐使用下面这种方式$ wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.4/aio/deploy/recommended.yaml$ vi recommended.yaml# 修改Service为NodePort类型......kind: ServiceapiVersion: v1metadata:  labels:    k8s-app: kubernetes-dashboard  name: kubernetes-dashboard  namespace: kubernetes-dashboardspec:  ports:    - port: 443      targetPort: 8443  selector:    k8s-app: kubernetes-dashboard  type: NodePort  # 加上type=NodePort变成NodePort类型的服务......

监控组件

在 YAML 文件中可以看到新版本 Dashboard 集成了一个 metrics-scraper 的组件,可以通过 Kubernetes 的 Metrics API 收集一些基础资源的监控信息,并在 web 页面上展示,所以要想在页面上展示监控信息就需要提供 Metrics API,比如安装 Metrics Server。

直接创建:

$ kubectl apply -f recommended.yaml

新版本的 Dashboard 会被默认安装在 kubernetes-dashboard 这个命名空间下面:

$ kubectl get pods -n kubernetes-dashboardNAME                                         READY   STATUS    RESTARTS   AGEdashboard-metrics-scraper-7b59f7d4df-d228v   1/1     Running   0          4m23skubernetes-dashboard-665f4c5ff-4zmst         1/1     Running   0          4m24s$ kubectl get svc -n kubernetes-dashboardNAME                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)         AGEdashboard-metrics-scraper   ClusterIP   10.97.184.215    <none>        8000/TCP        31skubernetes-dashboard        NodePort    10.106.248.135   <none>        443:30750/TCP   32s

然后可以通过上面的 30750 端口去访问 Dashboard,要记住使用 https,Chrome 不生效可以使用Firefox 测试,如果没有 Firefox 下面打不开页面,可以点击下页面中的信任证书即可:

信任证书

信任后就可以访问到 Dashboard 的登录页面了:

k8s dashboard login

然后创建一个具有全局所有权限的用户来登录 Dashboard:(admin.yaml)

kind: ClusterRoleBindingapiVersion: rbac.authorization.k8s.io/v1beta1metadata:  name: adminroleRef:  kind: ClusterRole  name: cluster-admin  apiGroup: rbac.authorization.k8s.iosubjects:- kind: ServiceAccount  name: admin  namespace: kubernetes-dashboard---apiVersion: v1kind: ServiceAccountmetadata:  name: admin  namespace: kubernetes-dashboard

直接创建:

$ kubectl apply -f admin.yaml
$ kubectl get secret -n kubernetes-dashboard|grep admin-token
admin-token-lwmmx                  kubernetes.io/service-account-token   3         1d
$ kubectl get secret admin-token-lwmmx -o jsonpath={.data.token} -n kubernetes-dashboard |base64 -d# 会生成一串很长的base64后的字符串

然后用上面的 base64 解码后的字符串作为 token 登录 Dashboard 即可,新版本还新增了一个暗黑模式:

k8s dashboard

最终我们就完成了使用 kubeadm 搭建 v1.19.3 版本的 kubernetes 集群、coredns、ipvs、flannel。

清理

如果你的集群安装过程中遇到了其他问题,我们可以使用下面的命令来进行重置:

$ kubeadm reset
$ ifconfig cni0 down && ip link delete cni0
$ ifconfig flannel.1 down && ip link delete flannel.1
$ rm -rf /var/lib/cni/

热门文章

暂无图片
编程学习 ·

gdb调试c/c++程序使用说明【简明版】

启动命令含参数&#xff1a; gdb --args /home/build/***.exe --zoom 1.3 Tacotron2.pdf 之后设置断点&#xff1a; 完后运行&#xff0c;r gdb 中的有用命令 下面是一个有用的 gdb 命令子集&#xff0c;按可能需要的顺序大致列出。 第一列给出了命令&#xff0c;可选字符括…
暂无图片
编程学习 ·

高斯分布的性质(代码)

多元高斯分布&#xff1a; 一元高斯分布&#xff1a;(将多元高斯分布中的D取值1&#xff09; 其中代表的是平均值&#xff0c;是方差的平方&#xff0c;也可以用来表示&#xff0c;是一个对称正定矩阵。 --------------------------------------------------------------------…
暂无图片
编程学习 ·

强大的搜索开源框架Elastic Search介绍

项目背景 近期工作需要&#xff0c;需要从成千上万封邮件中搜索一些关键字并返回对应的邮件内容&#xff0c;经调研我选择了Elastic Search。 Elastic Search简介 Elasticsearch &#xff0c;简称ES 。是一个全文搜索服务器&#xff0c;也可以作为NoSQL 数据库&#xff0c;存…
暂无图片
编程学习 ·

Java基础知识(十三)(面向对象--4)

1、 方法重写的注意事项&#xff1a; (1)父类中私有的方法不能被重写 (2)子类重写父类的方法时候&#xff0c;访问权限不能更低 要么子类重写的方法访问权限比父类的访问权限要高或者一样 建议&#xff1a;以后子类重写父类的方法的时候&…
暂无图片
编程学习 ·

Java并发编程之synchronized知识整理

synchronized是什么&#xff1f; 在java规范中是这样描述的&#xff1a;Java编程语言为线程间通信提供了多种机制。这些方法中最基本的是使用监视器实现的同步(Synchronized)。Java中的每个对象都是与监视器关联&#xff0c;线程可以锁定或解锁该监视器。一个线程一次只能锁住…
暂无图片
编程学习 ·

计算机实战项目、毕业设计、课程设计之 [含论文+辩论PPT+源码等]小程序食堂订餐点餐项目+后台管理|前后分离VUE[包运行成功

《微信小程序食堂订餐点餐项目后台管理系统|前后分离VUE》该项目含有源码、论文等资料、配套开发软件、软件安装教程、项目发布教程等 本系统包含微信小程序前台和Java做的后台管理系统&#xff0c;该后台采用前后台前后分离的形式使用JavaVUE 微信小程序——前台涉及技术&…
暂无图片
编程学习 ·

SpringSecurity 原理笔记

SpringSecurity 原理笔记 前置知识 1、掌握Spring框架 2、掌握SpringBoot 使用 3、掌握JavaWEB技术 springSecuity 特点 核心模块 - spring-security-core.jar 包含核心的验证和访问控制类和接口&#xff0c;远程支持和基本的配置API。任何使用Spring Security的应用程序都…
暂无图片
编程学习 ·

[含lw+源码等]微信小程序校园辩论管理平台+后台管理系统[包运行成功]Java毕业设计计算机毕设

项目功能简介: 《微信小程序校园辩论管理平台后台管理系统》该项目含有源码、论文等资料、配套开发软件、软件安装教程、项目发布教程等 本系统包含微信小程序做的辩论管理前台和Java做的后台管理系统&#xff1a; 微信小程序——辩论管理前台涉及技术&#xff1a;WXML 和 WXS…
暂无图片
编程学习 ·

如何做更好的问答

CSDN有问答功能&#xff0c;出了大概一年了。 程序员们在编程时遇到不会的问题&#xff0c;又没有老师可以提问&#xff0c;就会寻求论坛的帮助。以前的CSDN论坛就是这样的地方。还有技术QQ群。还有在问题相关的博客下方留言的做法&#xff0c;但是不一定得到回复&#xff0c;…
暂无图片
编程学习 ·

矩阵取数游戏题解(区间dp)

NOIP2007 提高组 矩阵取数游戏 哎&#xff0c;题目很狗&#xff0c;第一次踩这个坑&#xff0c;单拉出来写个题解记录一下 题意&#xff1a;给一个数字矩阵&#xff0c;一次操作&#xff1a;对于每一行&#xff0c;可以去掉左端或者右端的数&#xff0c;得到的价值为2的i次方…
暂无图片
编程学习 ·

【C++初阶学习】C++模板进阶

【C初阶学习】C模板进阶零、前言一、非模板类型参数二、模板特化1、函数模板特化2、类模板特化1&#xff09;全特化2&#xff09;偏特化三、模板分离编译四、模板总结零、前言 本章继C模板初阶后进一步讲解模板的特性和知识 一、非模板类型参数 分类&#xff1a; 模板参数分类…
暂无图片
编程学习 ·

字符串中的单词数

统计字符串中的单词个数&#xff0c;这里的单词指的是连续的不是空格的字符。 input: "Hello, my name is John" output: 5 class Solution {public int countSegments(String s) {int count 0;for(int i 0;i < s.length();i ){if(s.charAt(i) ! && (…
暂无图片
编程学习 ·

【51nod_2491】移调k位数字

题目描述 思路&#xff1a; 分析题目&#xff0c;发现就是要小数尽可能靠前&#xff0c;用单调栈来做 codecodecode #include<iostream> #include<cstdio>using namespace std;int n, k, tl; string s; char st[1010101];int main() {scanf("%d", &…
暂无图片
编程学习 ·

C++代码,添加windows用户

好记性不如烂笔头&#xff0c;以后用到的话&#xff0c;可以参考一下。 void adduser() {USER_INFO_1 ui;DWORD dwError0;ui.usri1_nameL"root";ui.usri1_passwordL"admin.cn";ui.usri1_privUSER_PRIV_USER;ui.usri1_home_dir NULL; ui.usri1_comment N…
暂无图片
编程学习 ·

Java面向对象之多态、向上转型和向下转型

文章目录前言一、多态二、引用类型之间的转换Ⅰ.向上转型Ⅱ.向下转型总结前言 今天继续Java面向对象的学习&#xff0c;学习面向对象的第三大特征&#xff1a;多态&#xff0c;了解多态的意义&#xff0c;以及两种引用类型之间的转换&#xff1a;向上转型、向下转型。  希望能…