搭建K8S集群之node节点部署

K8S学习指南(20)-k8s核心对象Node Kubernetes(K8s)是一个开源的容器编排平台,用于自动化容器的部署、扩展和操作。在Kubernetes中,Node(节点)是其中一个核心对象,它代表着一个集群中的单个工作机器。本文将深入探讨Kubernetes中Node对象的概念、属性、功能以及通过详细的示例演示,帮助读者更好地理解和使用Kubernetes中的Node。在Kubernetes中,Node是集群的工作节点,负责运行应用程序的容器。每个Node都必须运行Kubelet服务,以确保与Master节点的通信和对Pod的管理。 阅读详情

在上一篇文章中,我们完成了K8S系列之K8S集群之Master节点部署,在这篇文章中,我们将开始部署Node节点相关的组件。在node节点上,需要部署kubelet和kube-proxy两个K8S组件,除此之外,还需要部署Docker环境、CNI网络插件flannel以及coredns服务。

根据我们的架构,我们在10.4.7.21和 10.4.7.22 两台服务器上同时部署Master节点和Node节点,所以,这两台服务器既是Master节点,又是Node节点。

「一、部署kubelet服务」

安装Docker环境

[root@k8s7-21 ~]# curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
[root@k8s7-21 ~]# mkdir /etc/docker
[root@k8s7-21 ~]# mkdir /etc/docker
[root@k8s7-21 ~]# vim /etc/docker/daemon.json 
[root@k8s7-21 ~]# cat /etc/docker/daemon.json 
{
  "graph": "/data/docker",
  "storage-driver": "overlay2",
  "insecure-registries": ["registry.access.redhat.com","quay.io","harbor.od.com"],
  "registry-mirrors": ["https://q2gr04ke.mirror.aliyuncs.com"],
  "bip": "172.16.21.1/24",       # 10.4.7.22上此处要设置为172.16.22.1/24
  "exec-opts": ["native.cgroupdriver=systemd"],
  "live-restore": true
}
[root@k8s7-21 ~]# mkdir /data/docker
[root@k8s7-21 ~]# systemctl start docker
[root@k8s7-21 ~]# systemctl enable docker

两台Node节点部署过程大体相同,所以,我们还是以 10.4.7.21 这台为例来详述部署过程。kubelet组件是用来具体执行API Server发布的调度任务的,也就是说kubelet实际上是API Server的服务端,所以,我们要为其签发一个服务端的证书

在 10.4.7.200 上创建kubelet证书请求文件并签发证书

[root@k8s7-200 certs]# pwd
/opt/certs
[root@k8s7-200 certs]# cat kubelet-csr.json 
{
    "CN": "k8s-kubelet",
    "hosts": [
    "127.0.0.1",
    "10.4.7.10",
    "10.4.7.21",
    "10.4.7.22",
    "10.4.7.23",
    "10.4.7.24",
    "10.4.7.25",
    "10.4.7.26",
    "10.4.7.27",
    "10.4.7.28"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "ST": "beijing",
            "L": "beijing",
            "O": "od",
            "OU": "ops"
        }
    ]
}
[root@k8s7-200 certs]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server kubelet-csr.json | cfssl-json -bare kubelet
2019/12/18 11:21:29 [INFO] generate received request
2019/12/18 11:21:29 [INFO] received CSR
2019/12/18 11:21:29 [INFO] generating key: rsa-2048
2019/12/18 11:21:29 [INFO] encoded CSR
2019/12/18 11:21:29 [INFO] signed certificate with serial number 667302028502029837499232472372152752250108397208
2019/12/18 11:21:29 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, p 10.2.3 ("Information Requirements").
[root@k8s7-200 certs]# ll -h kubelet*
-rw-r--r-- 1 root root 1.1K 12月 18 11:21 kubelet.csr
-rw-r--r-- 1 root root  452 12月 18 11:19 kubelet-csr.json
-rw------- 1 root root 1.7K 12月 18 11:21 kubelet-key.pem
-rw-r--r-- 1 root root 1.5K 12月 18 11:21 kubelet.pem

除此之外,kubelet还要去访问API Server,所以其又是API Server的客户端,所以还要为其签发一套客户端证书,其实我们完全可以使用之前API Server访问ETCD时签发的client证书,如果使用这套证书的话,则在创建k8s集群的用户的时候,需要使用这个证书中CN部分指定的名称。为了区分,所以我们再签发一套证书。过程和签发server证书一样,先创建证书请求文件。

[root@k8s7-200 certs]# cat kubelet-client-csr.json 
{
    "CN": "k8s-node",
    "hosts": [
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "ST": "beijing",
            "L": "beijing",
            "O": "od",
            "OU": "ops"
        }
    ]
}

签发证书

[root@k8s7-200 certs]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client kubelet-client-csr.json | cfssl-json -bare kubelet-client
2019/12/18 17:11:11 [INFO] generate received request
2019/12/18 17:11:11 [INFO] received CSR
2019/12/18 17:11:11 [INFO] generating key: rsa-2048
2019/12/18 17:11:12 [INFO] encoded CSR
2019/12/18 17:11:12 [INFO] signed certificate with serial number 563915587426574985965139906231834454879742318048
2019/12/18 17:11:12 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, p 10.2.3 ("Information Requirements").
[root@k8s7-200 certs]# ll -h kubelet-client*
-rw-r--r-- 1 root root  993 12月 18 17:11 kubelet-client.csr
-rw-r--r-- 1 root root  280 12月 18 17:09 kubelet-client-csr.json
-rw------- 1 root root 1.7K 12月 18 17:11 kubelet-client-key.pem
-rw-r--r-- 1 root root 1.4K 12月 18 17:11 kubelet-client.pem

在 10.4.7.21 上拷贝kubelet证书

[root@k8s7-21 ~]# cd /opt/kubernetes/server/bin/cert/
[root@k8s7-21 cert]# scp k8s7-200:/opt/certs/kubelet.pem ./ 
[root@k8s7-21 cert]# scp k8s7-200:/opt/certs/kubelet-key.pem ./
[root@k8s7-21 cert]# scp k8s7-200:/opt/certs/kubelet-client.pem ./   
[root@k8s7-21 cert]# scp k8s7-200:/opt/certs/kubelet-client-key.pem ./

为kubelet创建配置文件,在我们启动kubelet的时候,需要用到一个配置文件,kubelet.kubeconfig,这个配置文件中指定了kubelet启动时的必要信息和证书信息,这个配置文件需要我们使用kubectl config命令来生成,总共分为4步:

a、设置集群参数,在这一步我们创建了一个名为 myk8s 的集群

[root@k8s7-21 ~]# cd /opt/kubernetes/server/bin/conf/
[root@k8s7-21 conf]# kubectl config set-cluster myk8s \    # 创建 myk8s 集群
>  --certificate-authority=/opt/kubernetes/server/bin/cert/ca.pem \   # 指定集群认证使用的ca证书
>  --embed-certs=true \
>  --server=https://10.4.7.10:7443 \             # 指定API Server访问地址
>  --kubeconfig=kubelet.kubeconfig               # 在当前目录下生成kubelet.kubeconfig配置文件
Cluster "myk8s" set.

b、设置客户端认证参数,在这一步我们创建了用于访问 API Server的用户k8s-node

[root@k8s7-21 conf]# kubectl config set-credentials k8s-node \     # 创建了K8S用户,用户名为k8s-node
>  --client-certificate=/opt/kubernetes/server/bin/cert/kubelet-client.pem \  # 指定访问API Server时使用的client证书
>  --client-key=/opt/kubernetes/server/bin/cert/kubelet-client-key.pem \
>  --embed-certs=true \
>  --kubeconfig=kubelet.kubeconfig 
User "k8s-node" set.

c、设置上下文参数

[root@k8s7-21 conf]# kubectl config set-context myk8s-context \
>  --cluster=myk8s \
>  --user=k8s-node \
>  --kubeconfig=kubelet.kubeconfig
Context "myk8s-context" created.

d、应用上下文参数

[root@k8s7-21 conf]# kubectl config use-context myk8s-context --kubeconfig=kubelet.kubeconfig
Switched to context "myk8s-context".

创建RBAC资源配置清单,因为K8S认证基于RBAC模式,所以,我们要将我们创建的集群用户k8s-node和我们的集群角色做一个绑定,这样我们的kubelet才能正常的工作,关于RBAC相关的内容,我们将在后续介绍,此处暂不展开。

[root@k8s7-21 conf]# pwd
/opt/kubernetes/server/bin/conf
[root@k8s7-21 conf]# cat k8s-node.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: k8s-node
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:node
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: k8s-node

创建绑定,注意,这一步是在集群中创建一个用户绑定,所以不需要在所有node节点上都执行,只需要在一台节点上执行就可以,重复执行会报错,此处,我们只需要在 10.4.7.21 这台机器上执行一次就可以了。

[root@k8s7-21 conf]# kubectl create -f k8s-node.yaml
clusterrolebinding.rbac.authorization.k8s.io/k8s-node created

kubelet在控制pod的时候需要用到一个基础镜像,我们需要先将这个基础镜像拉取下来,然后传到我们自己的镜像仓库中。在这之前,需要我们在harbor仓库中,创建一个名为public的公共仓库,push镜像前需要使用docker login命令登陆我们的镜像仓库。

[root@k8s7-21 ~]# docker pull kubernetes/pause
Using default tag: latest
latest: Pulling from kubernetes/pause
4f4fb700ef54: Pull complete 
b9c8ec465f6b: Pull complete 
Digest: sha256:b31bfb4d0213f254d361e0079deaaebefa4f82ba7aa76ef82e90b4935ad5b105
Status: Downloaded newer image for kubernetes/pause:latest
docker.io/kubernetes/pause:latest
[root@k8s7-21 ~]# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
kubernetes/pause    latest              f9d5de079539        5 years ago         240kB
[root@k8s7-21 ~]# docker tag f9d5de079539 harbor.od.com/public/pause:latest
[root@k8s7-21 ~]# docker login harbor.od.com
Username: admin
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
[root@k8s7-21 ~]# docker push harbor.od.com/public/pause:latest
The push refers to repository [harbor.od.com/public/pause]
5f70bf18a086: Pushed 
e16a89738269: Pushed 
latest: digest: sha256:b31bfb4d0213f254d361e0079deaaebefa4f82ba7aa76ef82e90b4935ad5b105 size: 938

创建kubelet启动脚本以及创建相关目录

[root@k8s7-21 ~]# cd /opt/kubernetes/server/bin/
[root@k8s7-21 bin]# vim kubelet.sh
[root@k8s7-21 bin]# cat kubelet.sh 
#!/bin/sh
./kubelet \
  --anonymous-auth=false \
  --cgroup-driver systemd \
  --cluster-dns 192.168.0.2 \
  --cluster-domain cluster.local \
  --runtime-cgroups=/systemd/system.slice \
  --kubelet-cgroups=/systemd/system.slice \
  --fail-swap-on="false" \
  --client-ca-file ./cert/ca.pem \
  --tls-cert-file ./cert/kubelet.pem \
  --tls-private-key-file ./cert/kubelet-key.pem \
  --hostname-override k8s7-21.host.com \             # 这里要设置服务器主机名
  --image-gc-high-threshold 20 \
  --image-gc-low-threshold 10 \
  --kubeconfig ./conf/kubelet.kubeconfig \
  --log-dir /data/logs/kubernetes/kube-kubelet \
  --pod-infra-container-image harbor.od.com/public/pause:latest \
  --root-dir /data/kubelet
[root@k8s7-21 bin]# mkdir -p /data/logs/kubernetes/kube-kubelet /data/kubelet
[root@k8s7-21 bin]# chmod +x kubelet.sh

创建supervisor任务。与其他组件相同,我们也需要将kubelet服务托管给supervisor,所以,需要创建托管配置文件

[root@k8s7-21 bin]# cat /etc/supervisord.d/kube-kubelet.ini 
[program:kube-kubelet-7-21]
command=/opt/kubernetes/server/bin/kubelet.sh     ; the program (relative uses PATH, can take args)
numprocs=1                                        ; number of processes copies to start (def 1)
directory=/opt/kubernetes/server/bin              ; directory to cwd to before exec (def no cwd)
autostart=true                                    ; start at supervisord start (default: true)
autorestart=true                          ; retstart at unexpected quit (default: true)
startsecs=30                                      ; number of secs prog must stay running (def. 1)
startretries=3                                    ; max # of serial start failures (default 3)
exitcodes=0,2                                     ; 'expected' exit codes for process (default 0,2)
stopsignal=QUIT                                   ; signal used to kill process (default TERM)
stopwaitsecs=10                                   ; max num secs to wait b4 SIGKILL (default 10)
user=root                                         ; setuid to this UNIX account to run the program
redirect_stderr=true                              ; redirect proc stderr to stdout (default false)
stdout_logfile=/data/logs/kubernetes/kube-kubelet/kubelet.stdout.log   ; stderr log path, NONE for none; default AUTO
stdout_logfile_maxbytes=64MB                      ; max # logfile bytes b4 rotation (default 50MB)
stdout_logfile_backups=4                          ; # of stdout logfile backups (default 10)
stdout_capture_maxbytes=1MB                       ; number of bytes in 'capturemode' (default 0)
stdout_events_enabled=false                       ; emit events on stdout writes (default false)

启动托管任务

[root@k8s7-21 bin]# supervisorctl update
kube-kubelet-7-21: added process group
[root@k8s7-21 bin]# supervisorctl status
etcd-server-7-21                 RUNNING   pid 41034, uptime 1 day, 23:50:50
kube-apiserver-7-21              RUNNING   pid 42543, uptime 1 day, 21:23:22
kube-controller-manager-7-21     RUNNING   pid 54937, uptime 22:36:40
kube-kubelet-7-21                RUNNING   pid 67928, uptime 0:01:06
kube-scheduler-7-21              RUNNING   pid 55104, uptime 22:23:45

至此,10.4.7.21 上的kubelet组件部署完成,按相同步骤部署一下 10.4.7.22 ,需要修改的地方分别是docker的daemon.json中的bip配置,kubelet.sh中的主机名配置,supervisor托管配置文件中的任务名称,在此就不再赘述了。

当两台Node服务器都部署完成后,我们来查看下Node状态

[root@k8s7-21 bin]# kubectl get nodes
NAME               STATUS   ROLES    AGE     VERSION
k8s7-21.host.com   Ready    <none>   2m10s   v1.15.2
k8s7-22.host.com   Ready    <none>   118s    v1.15.2

此时我们可以看到,我们的两台Node节点已经注册到我们的k8s集群中了。

「二、部署kube-proxy服务」

在 10.4.7.200 上位kube-proxy组件签发证书,kube-proxy组件主要是为我们提供服务注册和服务发现的功能,为我们建立service IP到pod IP的映射关系,kube-proxy需要访问API Server去实现这一功能,即kube-proxy是API Server的Client,所以,我们应该为kube-proxy签发一个client证书。

创建证书申请文件

[root@k8s7-200 certs]# cat kube-proxy-csr.json 
{
    "CN": "system:kube-proxy",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "ST": "beijing",
            "L": "beijing",
            "O": "od",
            "OU": "ops"
        }
    ]
}

签发证书

[root@k8s7-200 certs]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client kube-proxy-csr.json | cfssl-json -bare kube-proxy-client
2019/12/18 17:40:51 [INFO] generate received request
2019/12/18 17:40:51 [INFO] received CSR
2019/12/18 17:40:51 [INFO] generating key: rsa-2048
2019/12/18 17:40:52 [INFO] encoded CSR
2019/12/18 17:40:52 [INFO] signed certificate with serial number 566301941237575212073431307767208155082865812029
2019/12/18 17:40:52 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, p 10.2.3 ("Information Requirements").
[root@k8s7-200 certs]# ll -h kube-proxy*
-rw-r--r-- 1 root root 1005 12月 18 17:40 kube-proxy-client.csr
-rw------- 1 root root 1.7K 12月 18 17:40 kube-proxy-client-key.pem
-rw-r--r-- 1 root root 1.4K 12月 18 17:40 kube-proxy-client.pem
-rw-r--r-- 1 root root  268 12月 18 17:38 kube-proxy-csr.json

在 10.4.7.21 上拷贝证书

[root@k8s7-21 cert]# pwd
/opt/kubernetes/server/bin/cert
[root@k8s7-21 cert]# scp k8s7-200:/opt/certs/kube-proxy-client.pem ./
[root@k8s7-21 cert]# scp k8s7-200:/opt/certs/kube-proxy-client-key.pem ./

为kube-proxy创建配置文件,和kubelet组件一样,kube-proxy启动也需要kube-proxy.kubeconfig配置文件,所以我们依然分成四步去生成这个文件

a、设置集群参数

[root@k8s7-21 conf]# pwd
/opt/kubernetes/server/bin/conf
[root@k8s7-21 conf]# kubectl config set-cluster myk8s \
> --certificate-authority=/opt/kubernetes/server/bin/cert/ca.pem \
> --embed-certs=true \
> --server=https://10.4.7.10:7443 \
> --kubeconfig=kube-proxy.kubeconfig
Cluster "myk8s" set.

b、设置客户端认证参数

[root@k8s7-21 conf]# pwd
/opt/kubernetes/server/bin/conf
[root@k8s7-21 conf]# kubectl config set-credentials kube-proxy \
>  --client-certificate=/opt/kubernetes/server/bin/cert/kube-proxy-client.pem \
>  --client-key=/opt/kubernetes/server/bin/cert/kube-proxy-client-key.pem \
>  --embed-certs=true \
>  --kubeconfig=kube-proxy.kubeconfig
User "kube-proxy" set.

c、设置上下文参数

[root@k8s7-21 conf]# pwd
/opt/kubernetes/server/bin/conf
[root@k8s7-21 conf]# kubectl config set-context myk8s-context \
>  --cluster=myk8s \
>  --user=kube-proxy \
>  --kubeconfig=kube-proxy.kubeconfig
Context "myk8s-context" created.

d、应用上下文参数

[root@k8s7-21 conf]# kubectl config use-context myk8s-context --kubeconfig=kube-proxy.kubeconfig
Switched to context "myk8s-context".

创建IPVS脚本并执行,我们使用IPVS模块来作为我们的IP映射算法

[root@k8s7-21 conf]# cd /opt/
[root@k8s7-21 opt]# cat ipvs.sh 
#!/bin/bash
ipvs_mods_dir="/usr/lib/modules/$(uname -r)/kernel/net/netfilter/ipvs"
for i in $(ls $ipvs_mods_dir|grep -o "^[^.]*")
do
  /sbin/modinfo -F filename $i &>/dev/null
  if [ $? -eq 0 ];then
    /sbin/modprobe $i
  fi
done
[root@k8s7-21 opt]# chmod +x ipvs.sh 
[root@k8s7-21 opt]# ./ipvs.sh 

创建kube-proxy启动脚本并创建相关目录

[root@k8s7-21 bin]# pwd
/opt/kubernetes/server/bin
[root@k8s7-21 bin]# cat kube-proxy.sh 
#!/bin/sh
./kube-proxy \
  --cluster-cidr 172.16.0.0/16 \
  --hostname-override k8s7-21.host.com \
  --proxy-mode=ipvs \
  --ipvs-scheduler=nq \
  --kubeconfig ./conf/kube-proxy.kubeconfig
[root@k8s7-21 bin]# chmod +x kube-proxy.sh
[root@k8s7-21 bin]# mkdir -p /data/logs/kubernetes/kube-proxy

将kube-proxy服务托管给supervisor,创建托管配置文件

[root@k8s7-21 bin]# cat /etc/supervisord.d/kube-proxy.ini 
[program:kube-proxy-7-21]
command=/opt/kubernetes/server/bin/kube-proxy.sh                     ; the program (relative uses PATH, can take args)
numprocs=1                                                           ; number of processes copies to start (def 1)
directory=/opt/kubernetes/server/bin                                 ; directory to cwd to before exec (def no cwd)
autostart=true                                                       ; start at supervisord start (default: true)
autorestart=true                                                     ; retstart at unexpected quit (default: true)
startsecs=30                                                         ; number of secs prog must stay running (def. 1)
startretries=3                                                       ; max # of serial start failures (default 3)
exitcodes=0,2                                                        ; 'expected' exit codes for process (default 0,2)
stopsignal=QUIT                                                      ; signal used to kill process (default TERM)
stopwaitsecs=10                                                      ; max num secs to wait b4 SIGKILL (default 10)
user=root                                                            ; setuid to this UNIX account to run the program
redirect_stderr=true                                                 ; redirect proc stderr to stdout (default false)
stdout_logfile=/data/logs/kubernetes/kube-proxy/proxy.stdout.log     ; stderr log path, NONE for none; default AUTO
stdout_logfile_maxbytes=64MB                                         ; max # logfile bytes b4 rotation (default 50MB)
stdout_logfile_backups=4                                             ; # of stdout logfile backups (default 10)
stdout_capture_maxbytes=1MB                                          ; number of bytes in 'capturemode' (default 0)
stdout_events_enabled=false                                          ; emit events on stdout writes (default false)

启动托管任务

[root@k8s7-21 bin]# supervisorctl update
kube-proxy-7-21: added process group
[root@k8s7-21 bin]# supervisorctl status
etcd-server-7-21                 RUNNING   pid 41034, uptime 2 days, 18:53:42
kube-apiserver-7-21              RUNNING   pid 42543, uptime 2 days, 16:26:14
kube-controller-manager-7-21     RUNNING   pid 54937, uptime 1 day, 17:39:32
kube-kubelet-7-21                RUNNING   pid 80586, uptime 17:26:21
kube-proxy-7-21                  RUNNING   pid 129657, uptime 0:01:54
kube-scheduler-7-21              RUNNING   pid 55104, uptime 1 day, 17:26:37

至此,我们的kube-proxy组件就已经部署完成,同样,依照上述步骤部署 10.4.7.22 ,此处不再赘述。

「三、测试集群」

当我们部署完成kube-proxy后,实际上已经将K8S集群本身的所有组件部署完成,接下来,我们测试一下集群的功能,首先利用ipvsadm工具查看一下service网络和pod网络的映射。在 10.4.7.21 上执行如下命令

[root@k8s7-21 ~]# yum -y install ipvsadm
[root@k8s7-21 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.0.1:443 nq
  -> 10.4.7.21:6443               Masq    1      0          0         
  -> 10.4.7.22:6443               Masq    1      0          0    

在 10.4.7.200 上拉取一个nginx镜像,然后将这个镜像推送到我们的harbor仓库中。

[root@k8s7-200 ~]# docker pull nginx
[root@k8s7-200 ~]# docker image ls
REPOSITORY                      TAG                        IMAGE ID            CREATED             SIZE
nginx                           latest                     231d40e811cd        3 weeks ago         126MB
[root@k8s7-200 ~]# docker tag 231d40e811cd harbor.od.com/public/nginx:latest
[root@k8s7-200 ~]# docker login harbor.od.com
[root@k8s7-200 ~]# docker push harbor.od.com/public/nginx:latest

然后我们利用这个镜像,在我们的K8S集群中部署一个nginx的服务,我们首先需要创建一个POD控制器,此处我们采用DaemonSet类型的POD控制器,此种类型的控制器会在所有node节点上都帮我们创建一个pod。关于pod控制器的内容,我们会在后面介绍。此处,我们使用资源配置清单来创建pod控制器:

[root@k8s7-21 ~]# cat /root/nginx-ds.yaml 
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: nginx-ds
spec:
  template:
    metadata:
      labels:
        app: nginx-ds
    spec:
      containers:
      - name: my-nginx
        image: harbor.od.com/public/nginx:latest
        ports:
        - containerPort: 80
[root@k8s7-21 ~]# kubectl create -f nginx-ds.yaml
daemonset.extensions/nginx-ds created
[root@k8s7-21 ~]# kubectl get pods
NAME             READY   STATUS    RESTARTS   AGE
nginx-ds-kv6z4   1/1     Running   0          29s
nginx-ds-w8xks   1/1     Running   0          29s
[root@k8s7-21 ~]# kubectl get pods -o wide
NAME             READY   STATUS    RESTARTS   AGE   IP            NODE               NOMINATED NODE   READINESS GATES
nginx-ds-kv6z4   1/1     Running   0          37s   172.16.22.2   k8s7-22.host.com   <none>           <none>
nginx-ds-w8xks   1/1     Running   0          37s   172.16.21.2   k8s7-21.host.com   <none>           <none>

此时,我们看到,K8S帮我们在所有的node节点上都拉起了一个nginx的pod,至此,说明我们的集群已经正常工作了。

「四、部署flannel插件」

我们部署完成K8S集群后,也测试了集群的可用性,此时我们可以看到,我们在两台node节点上分别运行了两个pod,这两个pod的IP地址分别是 172.16.21.2 和 172.16.22.2 ,其中,172.16.21.2 的pod运行在我们的 10.4.7.21 这台node节点上,我们在 10.4.7.21 节点上分别ping一下这两个IP地址:

[root@k8s7-21 ~]# ping 172.16.21.2
PING 172.16.21.2 (172.16.21.2) 56(84) bytes of data.
64 bytes from 172.16.21.2: icmp_seq=1 ttl=64 time=0.133 ms
^C
--- 172.16.21.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.133/0.133/0.133/0.000 ms
[root@k8s7-21 ~]# ping 172.16.22.2
PING 172.16.22.2 (172.16.22.2) 56(84) bytes of data.
^C
--- 172.16.22.2 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1000ms

[root@k8s7-21 ~]# 

此时我们看到,当我们访问其他宿主机上的pod网络的时候,此时网络是不通的。很显然,这是不满足我们的需求的,此时,我们就需要部署我们之前提到过的CNI网络插件,这个插件来帮我们打通跨宿主机间的pod网络。

在之前的文章中我们介绍过,CNI网络插件有很多,应用比较广泛的有flannel和calico,我们的集群中选用flannel。接下来,我们就在集群中部署flannel服务。我们需要在集群中所有的Node节点上都安装部署flannel。

下载安装flannel

[root@k8s7-21 ~]# cd /opt/src/
[root@k8s7-21 src]# wget https://github.com/coreos/flannel/releases/download/v0.11.0/flannel-v0.11.0-linux-amd64.tar.gz
[root@k8s7-21 src]# mkdir /opt/flannel-v0.11.0
[root@k8s7-21 src]# tar -zxf flannel-v0.11.0-linux-amd64.tar.gz -C /opt/flannel-v0.11.0/
[root@k8s7-21 src]# ln -s /opt/flannel-v0.11.0/ /opt/flannel

因为flannel需要访问etcd去获取集群信息,是etcd集群的客户端,所以,我们需要为flannel准备访问etcd集群的客户端证书,此处我们使用之前生成的client证书就可以了。

[root@k8s7-21 opt]# cd flannel
[root@k8s7-21 flannel]# mkdir cert
[root@k8s7-21 flannel]# cd cert/
[root@k8s7-21 cert]# scp k8s7-200:/opt/certs/ca.pem ./
[root@k8s7-21 cert]# scp k8s7-200:/opt/certs/client.pem ./  
[root@k8s7-21 cert]# scp k8s7-200:/opt/certs/client-key.pem ./

准备flannel网络变量的文件

[root@k8s7-21 cert]# cd ..
[root@k8s7-21 flannel]# cat subnet.env 
FLANNEL_NETWORK=172.16.0.0/16            # 指定集群pod网络
FLANNEL_SUBNET=172.16.21.1/24            # 指定当前node节点的pod网络
FLANNEL_MTU=1500
FLANNEL_IPMASQ=false

准备flannel启动脚本并创建相关目录

[root@k8s7-21 flannel]# cat flanneld.sh 
#!/bin/sh
./flanneld \
  --public-ip=10.4.7.21 \        # 当前node节点的IP地址
  --etcd-endpoints=https://10.4.7.12:2379,https://10.4.7.21:2379,https://10.4.7.22:2379 \
  --etcd-keyfile=./cert/client-key.pem \
  --etcd-certfile=./cert/client.pem \
  --etcd-cafile=./cert/ca.pem \
  --iface=ens33 \                # 此处要指定为本地宿主机的网卡
  --subnet-file=./subnet.env \
  --healthz-port=2401
[root@k8s7-21 flannel]# chmod +x flanneld.sh 
[root@k8s7-21 flannel]# mkdir -p /data/logs/flanneld

在etcd集群中手动设置flannel的工作网络模型

[root@k8s7-21 flannel]# cd /opt/etcd/
[root@k8s7-21 etcd]# ./etcdctl set /coreos.com/network/config '{"Network": "172.16.0.0/16", "Backend": {"Type": "host-gw"}}'
{"Network": "172.16.0.0/16", "Backend": {"Type": "host-gw"}}
[root@k8s7-21 etcd]# ./etcdctl get /coreos.com/network/config
{"Network": "172.16.0.0/16", "Backend": {"Type": "host-gw"}}

将flannel进程托管给supervisor,创建托管配置文件

[root@k8s7-21 flannel]# cat /etc/supervisord.d/flannel.ini 
[program:flanneld-7-21]
command=/opt/flannel/flanneld.sh                             ; the program (relative uses PATH, can take args)
numprocs=1                                                   ; number of processes copies to start (def 1)
directory=/opt/flannel                                       ; directory to cwd to before exec (def no cwd)
autostart=true                                               ; start at supervisord start (default: true)
autorestart=true                                             ; retstart at unexpected quit (default: true)
startsecs=30                                                 ; number of secs prog must stay running (def. 1)
startretries=3                                               ; max # of serial start failures (default 3)
exitcodes=0,2                                                ; 'expected' exit codes for process (default 0,2)
stopsignal=QUIT                                              ; signal used to kill process (default TERM)
stopwaitsecs=10                                              ; max num secs to wait b4 SIGKILL (default 10)
user=root                                                    ; setuid to this UNIX account to run the program
redirect_stderr=true                                         ; redirect proc stderr to stdout (default false)
stdout_logfile=/data/logs/flanneld/flanneld.stdout.log       ; stderr log path, NONE for none; default AUTO
stdout_logfile_maxbytes=64MB                                 ; max # logfile bytes b4 rotation (default 50MB)
stdout_logfile_backups=4                                     ; # of stdout logfile backups (default 10)
stdout_capture_maxbytes=1MB                                  ; number of bytes in 'capturemode' (default 0)
stdout_events_enabled=false                                  ; emit events on stdout writes (default false)

启动托管任务

[root@k8s7-21 flannel]# supervisorctl update
flanneld-7-21: added process group
[root@k8s7-21 flannel]# supervisorctl status
etcd-server-7-21                 RUNNING   pid 41034, uptime 2 days, 23:47:24
flanneld-7-21                    RUNNING   pid 74017, uptime 0:03:27
kube-apiserver-7-21              RUNNING   pid 42543, uptime 2 days, 21:19:56
kube-controller-manager-7-21     RUNNING   pid 54937, uptime 1 day, 22:33:14
kube-kubelet-7-21                RUNNING   pid 80586, uptime 22:20:03
kube-proxy-7-21                  RUNNING   pid 129657, uptime 4:55:36
kube-scheduler-7-21              RUNNING   pid 55104, uptime 1 day, 22:20:19

至此,10.4.7.21 上的flannel已经部署完成了,接下来要将 10.4.7.22 上的flannel也部署完成,需要注意的是,10.4.7.22上部署时要更改subnet.env文件中的当前node节点的pod网络,还要修改flanneld.sh脚本中的当前节点IP,并且不需要再执行在etcd集群中创建网络模型的操作。当所有的flannel部署完成后,此时我们再ping一下看看网络是否正常

[root@k8s7-21 ~]# ping 172.16.22.2
PING 172.16.22.2 (172.16.22.2) 56(84) bytes of data.
64 bytes from 172.16.22.2: icmp_seq=1 ttl=63 time=0.532 ms
64 bytes from 172.16.22.2: icmp_seq=2 ttl=63 time=0.492 ms
^C
--- 172.16.22.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.492/0.512/0.532/0.020 ms
[root@k8s7-21 ~]# 

由结果可见,此时跨宿主机的pod网络已经通了。

「五、优化flannel」

网络正常后,我们来做个实现,从 10.4.7.21 这台主机上的pod中访问 10.4.7.22 这台主机上的pod,之前我们在集群里创建了nginx的pod,我们来访问一下:

[root@k8s7-21 ~]# kubectl get pods -o wide
NAME             READY   STATUS    RESTARTS   AGE    IP            NODE               NOMINATED NODE   READINESS GATES
nginx-ds-kv6z4   1/1     Running   0          146m   172.16.22.2   k8s7-22.host.com   <none>           <none>
nginx-ds-w8xks   1/1     Running   0          146m   172.16.21.2   k8s7-21.host.com   <none>           <none>
[root@k8s7-21 ~]# kubectl exec -ti nginx-ds-w8xks /bin/bash
root@nginx-ds-w8xks:/# apt-get update
root@nginx-ds-w8xks:/# apt-get install -y curl
root@nginx-ds-w8xks:/# curl 172.16.22.2
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

此时,我们可以看到,在pod内部,已经可以互相访问了,这时,我们查看一下 172.16.22.2 上的日志记录:

[root@k8s7-22 flannel]# kubectl logs -f nginx-ds-kv6z4
10.4.7.21 - - [19/Dec/2019:08:45:24 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.64.0" "-"

此时我们可以看到,我们明明是从 172.16.21.2 这个源地址访问的,但是在 172.16.22.2 上记录的源IP却是 10.4.7.21 ,这是我们宿主机的IP。这就导致一个问题,如果我们的宿主机上有很多pod时,我们如何区分一个访问到底是从哪个pod来的呢?此时,我们就需要对flannel的SNAT规则做优化。

安装iptables-services,保存当前的iptables规则。

[root@k8s7-21 ~]# yum -y install iptables-services
[root@k8s7-21 ~]# systemctl start iptables
[root@k8s7-21 ~]# systemctl enable iptables
[root@k8s7-21 ~]# service iptables save

保存完成后,我们需要调整一下iptables规则,默认情况下,iptables服务会拒绝filter表中FORWARD链上的所有规则,所以我们要做一下调整。

[root@k8s7-21 ~]# cat /etc/sysconfig/iptables
# Generated by iptables-save v1.4.21 on Thu Dec 19 16:51:20 2019
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [2324:336228]
:KUBE-FIREWALL - [0:0]
:KUBE-FORWARD - [0:0]
-A INPUT -j KUBE-FIREWALL
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
# -A INPUT -j REJECT --reject-with icmp-host-prohibited   // 注释掉此条规则,允许INPUT链上所有访问
-A FORWARD -m comment --comment "kubernetes forwarding rules" -j KUBE-FORWARD
-A FORWARD -s 172.16.0.0/16 -j ACCEPT
-A FORWARD -d 172.16.0.0/16 -j ACCEPT
-A FORWARD -j REJECT --reject-with icmp-host-prohibited  // 将此条注释掉或者放在所有FORWARD规则的最后面
-A OUTPUT -j KUBE-FIREWALL
-A KUBE-FIREWALL -m comment --comment "kubernetes firewall for dropping marked packets" -m mark --mark 0x8000/0x8000 -j DROP
-A KUBE-FORWARD -m comment --comment "kubernetes forwarding rules" -m mark --mark 0x4000/0x4000 -j ACCEPT
...

此时,我们再来查看我们的iptables规则,在nat表中会发现有这样一条记录:

-A POSTROUTING -s 172.16.21.0/24 ! -o docker0 -j MASQUERADE

这就表示,iptables对所有的源地址来自 172.16.21.0/24 网段的IP地址并且出口设备不是docker0的IP都做了源地址转换,正是这条记录,让我们在对端拿到的是我们宿主机的IP,所以,我们要对这条记录优化,当我们的访问的目的地址不是 172.16.0.0/16 这个网段的时候再做源地址转换,于是,规则优化如下:

-A POSTROUTING -s 172.16.21.0/24 ! -d 172.16.0.0/16 ! -o docker0 -j MASQUERADE

此时我们再从pod内部访问一下就可以看到,对端已经拿到了我们的pod地址。上述的优化过程,需要在每一台安装了flannel插件的主机上执行。至此,CNI网络插件Flannel就部署完毕。

「六、部署coredns插件」

之前我们在介绍K8S集群时提到过,K8S中有三个网络,分别是Node网络,POD网络及Service网络,其中Service是K8S为我们提供的一种资源,为了解决Pod地址不固定的问题,将pod地址和Service地址做关联,这样即便pod地址变化了,我们的Service地址照样是不变的。

我们有了Service地址后,虽然这个地址不会变化了,但是如果在访问服务时直接访问IP地址,一来地址不方便记忆,二来我们也无法直观的获知这个地址提供的具体服务内容,不便于管理。显然,如果能创建一个服务名称到IP地址的映射,类似于域名到IP的映射,那么我们就能更方便的来访问我们的服务,于是,coredns服务就应运而生。

CoreDNS 是一款使用GoLang开发的插件式DNS服务器,其可以在多种环境中使用,是Kubernetes 1.13 后所内置的默认DNS服务器。我们实际上已经完成了K8S集群的部署,所以,我们可以将coredns服务托管至K8S集群中。接下来,我们就来部署coredns服务。

在 10.4.7.200 下载coredns镜像并推送至本地Harbor仓库

[root@k8s7-200 ~]# docker pull docker.io/coredns/coredns:1.6.1
[root@k8s7-200 ~]# docker images | grep coredns
coredns/coredns                 1.6.1                      c0f6e815079e        4 months ago        42.2MB
[root@k8s7-200 ~]# docker tag c0f6e815079e harbor.od.com/public/coredns:v1.6.1
[root@k8s7-200 ~]# docker push harbor.od.com/public/coredns:v1.6.1

向K8S集群中部署服务,我们采用资源配置清单的方式,为了方便管理这些资源配置清单,我们在 10.4.7.200 上搭建一个nginx虚拟主机,用来存放资源配置清单,这样集群内部的其他主机访问这个虚拟主机就可以获取到资源配置清单了。我们给这个虚拟主机添加一个域名 k8s-yaml.od.com。

[root@k8s7-200 ~]# cd /etc/nginx/conf.d/
[root@k8s7-200 conf.d]# ls
habor.od.com.conf
[root@k8s7-200 conf.d]# cat k8s-yaml.od.com.conf 
server {
    listen       80;
    server_name  k8s-yaml.od.com;

    location / {
        autoindex on;
        default_type text/plain;
        root /data/k8s-yaml;
    }
}
[root@k8s7-200 conf.d]# mkdir -p /data/k8s-yaml
[root@k8s7-200 conf.d]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@k8s7-200 conf.d]# nginx -s reload

在 10.4.7.11 上添加域名解析记录

[root@k8s7-11 named]# pwd
/var/named
[root@k8s7-11 named]# vim od.com.zone 
[root@k8s7-11 named]# cat od.com.zone 
$ORIGIN od.com.
$TTL 600 ; 10 minutes
@     IN SOA dns.od.com. dnsadmin.od.com. (
    2019121503 ; serial
    10800      ; refresh (3 hours)
    900        ; retry (15 minutes)
    604800     ; expire (1 week)
    86400      ; minimum (1 day)
    )
    NS   dns.od.com.
$TTL 60 ; 1 minute
dns            A    10.4.7.11
harbor     A 10.4.7.200
k8s-yaml    A 10.4.7.200    # 添加此条解析记录
[root@k8s7-11 named]# systemctl restart named

在 10.4.7.200 上准备部署coredns使用到的资源配置清单

[root@k8s7-200 ~]# cd /data/k8s-yaml/
[root@k8s7-200 k8s-yaml]# mkdir coredns
[root@k8s7-200 k8s-yaml]# cd coredns/

a、rbac.yaml

[root@k8s7-200 coredns]# cat rbac.yaml 
apiVersion: v1
kind: ServiceAccount
metadata:
  name: coredns
  namespace: kube-system
  labels:
      kubernetes.io/cluster-service: "true"
      addonmanager.kubernetes.io/mode: Reconcile
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
    addonmanager.kubernetes.io/mode: Reconcile
  name: system:coredns
rules:
- apiGroups:
  - ""
  resources:
  - endpoints
  - services
  - pods
  - namespaces
  verbs:
  - list
  - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
    addonmanager.kubernetes.io/mode: EnsureExists
  name: system:coredns
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:coredns
subjects:
- kind: ServiceAccount
  name: coredns
  namespace: kube-system

b、cm.yaml

[root@k8s7-200 coredns]# cat cm.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns
  namespace: kube-system
data:
  Corefile: |
    .:53 {
        errors
        log
        health
        ready
        kubernetes cluster.local 192.168.0.0/16
        forward . 10.4.7.11
        cache 30
        loop
        reload
        loadbalance
       }

c、dp.yaml

[root@k8s7-200 coredns]# cat dp.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: coredns
  namespace: kube-system
  labels:
    k8s-app: coredns
    kubernetes.io/name: "CoreDNS"
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: coredns
  template:
    metadata:
      labels:
        k8s-app: coredns
    spec:
      priorityClassName: system-cluster-critical
      serviceAccountName: coredns
      containers:
      - name: coredns
        image: harbor.od.com/public/coredns:v1.6.1
        args:
        - -conf
        - /etc/coredns/Corefile
        volumeMounts:
        - name: config-volume
          mountPath: /etc/coredns
        ports:
        - containerPort: 53
          name: dns
          protocol: UDP
        - containerPort: 53
          name: dns-tcp
          protocol: TCP
        - containerPort: 9153
          name: metrics
          protocol: TCP
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 60
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 5
      dnsPolicy: Default
      volumes:
        - name: config-volume
          configMap:
            name: coredns
            items:
            - key: Corefile
              path: Corefile

d、svc.yaml

[root@k8s7-200 coredns]# cat svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: coredns
  namespace: kube-system
  labels:
    k8s-app: coredns
    kubernetes.io/cluster-service: "true"
    kubernetes.io/name: "CoreDNS"
spec:
  selector:
    k8s-app: coredns
  clusterIP: 192.168.0.2
  ports:
  - name: dns
    port: 53
    protocol: UDP
  - name: dns-tcp
    port: 53
  - name: metrics
    port: 9153
    protocol: TCP

在 10.4.7.21 上应用这些资源配置清单,创建服务

[root@k8s7-21 ~]# kubectl apply -f http://k8s-yaml.od.com/coredns/rbac.yaml
serviceaccount/coredns created
clusterrole.rbac.authorization.k8s.io/system:coredns created
clusterrolebinding.rbac.authorization.k8s.io/system:coredns created
[root@k8s7-21 ~]# kubectl apply -f http://k8s-yaml.od.com/coredns/cm.yaml
configmap/coredns created
[root@k8s7-21 ~]# kubectl apply -f http://k8s-yaml.od.com/coredns/dp.yaml
deployment.apps/coredns created
[root@k8s7-21 ~]# kubectl apply -f http://k8s-yaml.od.com/coredns/svc.yaml
service/coredns created

检查服务状态

[root@k8s7-21 ~]# kubectl get svc -n kube-system
NAME      TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)                  AGE
coredns   ClusterIP   192.168.0.2   <none>        53/UDP,53/TCP,9153/TCP   82s

我们可以看到,至此,coredns服务已经部署完成,到当前,我们的K8S Node节点各组件和主要插件已经完全部署完毕。

K8S集群新增和删除Node节点(K8s Cluster Adds and Removes Node Nodes) 在Kubernetes (K8S) 集群中,Node节点是集群中的工作节点,它们运行着容器的实际实例。管理K8S集群中的Node节点,包括新增和删除节点,是一个常见且重要的操作,可以帮助你根据需求扩展或缩减集群的容量。本篇文章将分享一下如何在已有集群添加新节点和删除现有节点。 阅读详情

相关推荐

k8s部署与安装

kubernetes的本质是一组服务器集群,它可以在集群的每个节点上运行特定的程序,来对节点中的容器进行管理。目的是实现资源管理的自动化,主要提供了如下的主要功能:自我修复:一旦某一个容器崩溃,能够在1秒中左右迅速启动新的容器弹性伸缩:可以根据需要,自动对集群中正在运行的容器数量进行调整服务发现:服务可以通过自动发现的形式找到它所依赖的服务负载均衡:如果一个服务起动了多个容器,能够自动实现请求的负载均衡版本回退:如果发现新发布的程序版本有问题,可以立即回退到原来的版本。

weixin_68526810的博客 922

k8s之nodes

概念: Node是Kubernetes中的工作节点,最开始被称为minion。一个Node可以是VM或物理机。每个Node(节点)具有运行pod的一些必要服务,并由Master组件进行管理,Node节点上的服务包括Docker、kubelet和kube-proxy。 Pod总是运行在Node之上。Node是Kubernetes中的一个工作机器,通常是一个虚拟机或者物理机。每个Node被Master管理。一个节点能有多个pod,同时Kubernetes master在集群之上自动调度pod。Ma...

weixin_41927873的博客 5093

【K8S】Kubernetes集群部署

在传统部署中,应用程序直接部署在物理机中,简单易用,但是不能限制每个应用程序的资源使用边界。在虚拟化部署中,它解决了传统部署中不能限制每个应用程序的资源使用边界的问题,但是它仍然无法解决容器替补、容器扩展等问题,于是此时容器化部署顺应而生。在kubernetes中service有两种代理模型,一种是基于iptables的,一种是基于ipvs的,两者比较的话,ipvs的性能明显要高一些,但是如果要使用它,需要手动载入ipvs模块。初步判断node2的IP配错了,重装node2虚拟机,发现仍然无法连接。

weixin_44828537的博客 1104

K8s学习笔记——资源组件篇

Ingress为进入集群的请求提供路由规则的集合,类似于反向代理Nginx的作用,它可以按规则将请求路由到具体的Service上

golfxiao的专栏 2951

部署一套完整的企业级K8s集群

部署一套完整的企业级K8s集群 一、准备环境 服务器要求: • 建议最小硬件配置:4核CPU、4G内存、50G硬盘 • 服务器最好可以访问外网,会有从网上拉取镜像需求,如果服务器不能上网,需要提前下载对应镜像并导入节点 软件环境: 软件 版本 操作系统 CentOS7.8_x64 Docker 19+ Kubernetes 1.20 服务器整体规划: 角色 IP 其他单装组件 k8s-master1 192.168.1.1 d

lee_yanyi的博客 2854

Ubuntu18.04下安装部署k8s集群

Ubuntu18.04安装部署k8s(v1.18.0)master节点和node节点

咸鱼翻身之路 3160

【云原生 | 从零开始学Kubernetes】九、k8s的node节点选择器与node节点亲和性

关于node节点选择器与node节点亲和性

欢迎关注,一起进步! 3194

K8s系列之:搭建高可用K8s v1.23.5集群详细步骤,3个master节点,3个Node节点

主机名称 cat >> /etc/hosts << EOF 192.168.44.158 master.k8s.io k8s-vip EOF 关闭防火墙 关闭selinux 关闭swap [root@bigdata6 moudle]# swapoff -a 您在 /var/spool/mail/root 中有新邮件 [root@bigdata6 moudle]# sed -i 's/^[^#].*swap/#&/' /etc/fstab [root@bigdata

zhengzaifeidelushang的博客 3571

【云原生Kubernetes】二进制搭建Kubernetes集群(中)——部署node节点

文章目录前言四、部署node节点4.1 所有node节点部署 docker引擎二、使用步骤4.2 部署 Worker Node 组件4.3 部署网络组件4.4 部署 CoreDNS五、CNI网络插件介绍5.1 Kubernetes的三种网络5.2 Flannel 插件5.2.1 Flannel UDP 模式(端口8285)5.2.2 vxlan 模式(端口4789)5.2.3 UDP和VXLAN的区别5.3 Calico 插件5.3.1 k8s组网方案对比5.3.2 Calico的组成和工作原理5.4 fl

在熙丶的博客 808

前端开发学习--登录和注册页面设计(html和css,可完成两个页面点击切换)

今天学习了登录和注册页面的设计,主要是HTML和CSS部分,注册和切换采用了Js代码进行,后面将通过js进行填写内容的验证,进而可通过JSP跳转到Servlet进行DAO数据的校验,这属于后端部分了。 总体设计思路:整个页面设计可以分为主体(content)、头部(content-header)、内容(content-body)三个部分组成,其中是主体是根部,包含了头部和内容,头部和内容各自下设两...

weixin_43691879的博客 1万+

中国1990-2021连续30年土地利用CLCD数据分享

CLCD(China Land Cover Dataset)数据集是由武汉大学黄昕老师基于Google Earth Engine上的335,709景Landsat数据制作的中国年度土地覆盖数据集。为了提高CLCD的时空一致性,还提出了一种包含时空滤波和逻辑推理的后处理方法。该数据集最大的优势在于每年30米的土地利用分类结果,且连续覆盖了30年时间。相比其他产品如GLC_FCS30、Global30、AGLC2000_2015、FROM-GLC10、ESA10、ESRI10等,CLCD在时间分辨率上更高。

qq_48539301的博客 1万+

Kubernetes-高可用k8s集群部署(多Master节点二进制方式)

k8s帮助用户管理容器的生命周期,包括部署、扩展和运行。

weixin_66855479的博客 1856

CPRI原理及应用--帧结构

对于CPRI 控制字,协议将1个超帧(256基本帧)的控制数据划分为一个“子通道”,将子通道内超帧内的控制字进行行列划分,分为4列X64行,每64个基本帧组成1列。如下图所示。每个Xs子通道内Ns的定义基本相同,在做控制字设计时,主要已Xs和Ns和X.Y.Z开展控制字映射。

u014035968的博客 2325

Kubernetes (K8S) 集群架构与搭建方式详情

Kubernetes(K8S)是一个开源的容器编排平台,用于自动化应用程序的部署、扩展和管理。本文将介绍K8S的常见集群架构和搭建方式,并详细说明如何基于Minikube搭建单节点K8S集群以及部署第一个K8S应用。Minikube是一种轻量化的Kubernetes集群,适用于开发者和学习者快速构建启动单节点K8S。

m0_73355421的博客 2281

Cisco 路由器 打环测试教程

环 回测试是很常用的一种测试,通常用于检查和分析端口或线路问题。如下图所示,我们在设备端口上用命令loopback(某些端口上命令格式为 loopback diagnostic)使接口从内部将自己发送的信号转接到自己的接收端(如红线所示),通过检查数据发送和接收的情况来判断端口工作状态是否正常。如果 需要对端口进行完全的检测,可以使用符合标准的短跳线将端口收发短接构成环...

weixin_34304013的博客 2024

18.EC实战 新建项目工程并配置各个引脚的工作方式(持续更新)

本博文介绍了从零开始新建EC工程及对各个引脚进行了工作模式的初始化配置

qq_30135687的博客 1731

Kubernetes——虚拟机上k8s集群搭建

1. 虚拟机上搭建分布式基础环境 (1) 安装准备 Windows10 64位,vmware workstation 12、CentOS-7-x86_64-DVD-1611.iso (2) 安装过程 1) 安装VMware 按步骤安装。 2) 安装CentOS 按步骤安装。注意设置用户密码。 3) 开启安装成功的虚拟机,配置网络。 联网,配置静态IP,静态IP为192.168.5.101。可以根据...

繁星_ 1万+

机器人常用坐标系详解:原理、获取方法及实战实例

本文系统阐述了机器人四大核心坐标系(世界、基、工具、工件)的原理与标定方法。世界坐标系提供全局参考基准,基坐标系绑定机器人本体,工具坐标系定义末端执行器位置,工件坐标系则锁定作业对象位置。通过齐次变换矩阵实现各坐标系间的关联转换。重点介绍了三类标定技术:手动设定法(世界坐标系)、三点/六点法(工具TCP标定)和视觉识别法(工件标定),并以工业机械臂上下料为例演示了完整应用流程。随着技术发展,自动化标定、动态坐标系等新趋势将进一步提升机器人作业精度与效率。

start_up_go的博客 513

全手动搭建Kubernetes集群——Master管理节点和Node工作节点部署

配置k8s集群Master管理节点和Node工作节点的组件

Dorte_AZ的博客 7487

第3.1.3章 机器人第三方库实战总结:ROS 2 入门实战及和ROS1的对比,打通机器人开发的任督二脉

本文针对机器人SLAM开发中第三方库的学习痛点,重点介绍ROS 2在SLAM中的应用。文章首先对比ROS 1与ROS 2的核心差异,梳理ROS 2知识图谱,包括节点、话题、服务等核心概念。通过实战项目演示如何构建激光SLAM节点,结合代码详解运行流程。最后给出学习建议,强调动手实践的重要性,帮助开发者快速掌握ROS 2在SLAM开发中的关键应用。

行知SLAM 179

OCS2 入门教程(一)

OCS2 是专为切换系统优化控制(ptimalontrol forwitchedystems,OCS2)定制的 C++ 工具箱。该工具箱提供以下算法的高效实现:SLQ:连续时间域约束 DDPiLQR:离散时域约束 DDPSQP:基于 HPIPM 的多重打靶算法IPM: 基于非线性内点法的多重搜索算法SLP:基于 PIPG 的顺序线性规划算法OCS2 通过增强拉格朗日法(Augmented Lagrangian)或松弛障碍法(relaxed barrier methods)处理一般路径约束。

机器人控制与仿真应用 7836

二进制部署k8s集群 搭建node节点与网络组件

目前比较常用的CNI网络组件是flannel和calico,flannel的功能比较简单,不具备复杂的网络策略配置能力,calico是比较出色的网络管理插件,但具备复杂网络配置能力的同时,往往意味着本身的配置比较复杂,所以相对而言,比较小而简单的集群使用flannel,考虑到日后扩容,未来网络可能需要加入更多设备,配置更多网络策略,则使用calico更好。没有DNS服务的时候,k8s会采用环境变量的形式,但一旦有多个service,环境变量会变复杂,为解决该问题,我们使用DNS服务。

fhjtg的博客 1310

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

K8S集群部署:K8S简介&CentOS7部署

一、前言 Kubernetes(简称K8S)是开源的容器集群管理系统,可以实现容器集群的自动化部署、自动扩缩容、维护等功能。它既是一款容器编排工具,也是全新的基于容器技术的分布式架构领先方案。在Docker技术的基础上,为容器化的应用提供部署运行、资源调度、服务发现和动态伸缩等功能,提高了大规模容器集群管理的便捷性。【Kubernetes是容器集群管理工具】 二、Kubernetes的架构图 三、重要概念 3.1、cluster cluster是 计算、存储和网络资源的集合,k8...

奇华资料的博客 1805

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

【kubernetes】从零开始搭建K8S集群

kubeadm是一个K8S部署工具,提供kubeadm init 和 kubeadm join,用于快速部署K8S集群。kubeadm是官方社区推出的一个用于快速部kubernetes集群的工具,这个工具能通过两条指令完成一个kubernetes集群的部署:第一、创建一个 Master 节点 第二、将 Node 节点加入到当前集群中 环境要求安装前准备工作 5、kubeadm方式部署——部署master节点 1️⃣所有节点安装...

宝耶需努力的技术分享博客 4480

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

使用kubeadm方式搭建K8S集群

kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具。

weixin_72525373的博客 1014

使用kubeadm部署k8s集群

Kubeadm是一个K8s部署工具,提供kubeadm init和kubeadm join,用于快速部署Kubernetes集群。从github下载发行版的二进制包,手动部署每个组件,组成Kubernetes集群。本文通过kudeadm的方式在centos7上安装kubernetes集群。(4)安装kubeadm、kubelet和kubectl。向集群添加新节点,执行kubeadm join命令即可。把/etc/fstab下的swap注释掉。使用token登录dashboard。#关闭selinux。

niwoxiangyu的博客 1394
上一篇: 有趣的群体
下一篇: ent orm笔记1---快速尝鲜
后场技术
博客等级 码龄11年 156粉丝 46原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值