涛子 - 简单就是美

成单纯魁增,永继振国兴,克复宗清政,广开家必升

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

*** 参考 ***

https://kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/high-availability
https://www.golinuxcloud.com/kubernetes-tutorial
https://kairen-archived.github.io/2019/09/20/ironman2020/day05
https://github.com/kubernetes/kubeadm/blob/main/docs/ha-considerations.md#options-for-software-load-balancing
https://realsysadmin.com/www/2020/12/10/kicking-the-tires-on-kubernetes-part-4
https://www.cnblogs.com/yuezhimi/category/1340864.html?page=2

自我修复:在节点故障时重新启动失败的容器,替换和重新部署,保证预期的副本数量;杀死健康检查失败的容器,并且在未准备好之前不会处理客户端请求,确保线上服务不中断。
弹性伸缩:使用命令、UI或者基于CPU使用情况自动快速扩容和缩容应用程序实例,保证应用业务高峰并发时的高可用性;业务低峰时回收资源,以最小成本运行服务。
自动部署和回滚:K8S采用滚动更新策略更新应用,一次更新一个Pod,而不是同时删除所有Pod,如果更新过程中出现问题,将回滚更改,确保升级不受影响业务。
服务发现和负载均衡:K8S为多个容器提供一个统一访问入口(内部IP地址和一个DNS名称),并且负载均衡关联的所有容器,使得用户无需考虑容器IP问题。
机密和配置管理:管理机密数据和应用程序配置,而不需要把敏感数据暴露在镜像里,提高敏感数据安全性。并可以将一些常用的配置存储在K8S中,方便应用程序使用。
存储编排:挂载外部存储系统,无论是来自本地存储,公有云(如AWS),还是网络存储(如NFS、GlusterFS、Ceph)都作为集群资源的一部分使用,极大提高存储使用灵活性。
批处理:提供一次性任务,定时任务;满足批量数据处理和分析的场景。

一、服务器规划

  1. 使用堆叠(stacked)控制平面节点,其中etcd节点与控制平面节点共存, 使用外部etcd节点,其中etcd在与控制平面不同节点上运行
  2. 操作系统 CentOS Linux release 7.9.2009 (Core)
hostname category hardware eth0 eth1
vip 192.168.100.190
vm-191 master core*4 / 4g / 20GB 192.168.100.191 10.0.100.191
vm-192 master core*4 / 4g / 20GB 192.168.100.192 10.0.100.192
vm-193 master core*4 / 4g / 20GB 192.168.100.193 10.0.100.193
vm-194 etcd core*4 / 4g / 20GB 192.168.100.194 10.0.100.194
vm-195 etcd core*4 / 4g / 20GB 192.168.100.195 10.0.100.195
vm-196 etcd core*4 / 4g / 20GB 192.168.100.196 10.0.100.196
vm-197 worker core*4 / 4g / 20GB 192.168.100.197 10.0.100.197
vm-207 worker core*4 / 4g / 20GB 192.168.100.207 10.0.100.207
vm-208 worker core*4 / 4g / 20GB 192.168.100.208 10.0.100.208
vm-198 registry core*4 / 4g / 20GB 192.168.100.198 10.0.100.198

二、预安装

1. 静态指向(master & worker & ectd)

cat > /etc/hosts <<EOF
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

192.168.100.191 vm-191
192.168.100.192 vm-192
192.168.100.193 vm-193
192.168.100.194 vm-194
192.168.100.195 vm-195
192.168.100.196 vm-196
192.168.100.197 vm-197
192.168.100.207 vm-207
192.168.100.208 vm-208
192.168.100.198 vm-198
EOF

2. ssh信任登录

# vm-191
ssh-keygen -b 1024 -t rsa -P '' -f ~/.ssh/id_rsa

for i in 192 193 194 195 196 197 207 208; do ssh-copy-id -i .ssh/id_rsa.pub vm-$i; done
for i in 192 193 194 195 196 197 207 208; do scp /etc/hosts vm-$i:/etc; done

3. 修改内核配置

cat > /etc/modules-load.d/k8s.conf <<EOF
br_netfilter
EOF

cat > /etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

sysctl -p

for i in 192 193 194 195 196 197 207 208;  do scp /etc/modules-load.d/k8s.conf vm-$i:/etc/modules-load.d; done
for i in 192 193 194 195 196 197 207 208;  do scp /etc/sysctl.d/k8s.conf vm-$i:/etc/sysctl.d; done
for i in 192 193 194 195 196 197 207 208;  do ssh vm-$i 'sysctl -p'; done

4. 加载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
sh /etc/sysconfig/modules/ipvs.modules

for i in 192 193 194 195 196 197 207 208; do scp /etc/sysconfig/modules/ipvs.modules vm-$i:/etc/sysconfig/modules; done
for i in 192 193 194 195 196 197 207 208; do ssh vm-$i 'chmod 755 /etc/sysconfig/modules/ipvs.modules; sh /etc/sysconfig/modules/ipvs.modules'; done

5. 安装docker

# master & worker & ectd
cat > /etc/yum.repos.d/docker-ce.repo << EOF
[docker-ce-stable]
name=Docker CE Stable - \$basearch
baseurl=https://mirrors.nju.edu.cn/docker-ce/linux/centos/\$releasever/\$basearch/stable
enabled=1
gpgcheck=0
gpgkey=https://mirrors.nju.edu.cn/docker-ce/linux/centos/gpg
EOF

yum install -y docker-ce

cat > /etc/docker/daemon.json << EOF
{
  "registry-mirrors": ["https://registry.docker-cn.com", "http://hub-mirror.c.163.com", "https://docker.mirrors.ustc.edu.cn"],
  "insecure-registries": ["https://192.168.100.198:5000"],
  "exec-opts": ["native.cgroupdriver=systemd"]
}
EOF

systemctl restart docker  && systemctl enable docker 
docker version && docker info

for i in 192 193 194 195 196 197 207 208; do ssh vm-$i 'yum install -y docker-ce'; done
for i in 192 193 194 195 196 197 207 208; do scp /etc/docker/daemon.json vm-$i:/etc/docker; done
for i in 192 193 194 195 196 197 207 208; do ssh vm-$i 'systemctl enable docker && systemctl restart docker'; done

6. 安装kubernetes

# master & worker & ectd
cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.nju.edu.cn/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF

yum remove -y kubeadm kubectl kubelet && yum install -y kubeadm-1.21.6-0 kubectl-1.21.6-0 kubelet-1.21.6-0

for i in 192 193 194 195 196 197 207 208; do scp /etc/yum.repos.d/kubernetes.repo vm-$i:/etc/yum.repos.d; done
for i in 192 193 194 195 196 197 207 208; do ssh vm-$i 'yum remove -y kubeadm kubectl kubelet && yum install -y kubeadm-1.21.6-0 kubectl-1.21.6-0 kubelet-1.21.6-0'; done

三、etcd高可用集群

静态pod方式失败,原因未找到,使用docker单独部署

1. 配置kubelet

mkdir -p /var/lib/kubelet

cat > /var/lib/kubelet/config.yaml << EOF
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta2
cgroupDriver: "systemd"
address: "127.0.0.1"
staticPodPath: "/etc/kubernetes/manifests"
authentication:
  x509:
    clientCAFile: "/etc/kubernetes/pki/etcd/ca.crt"
    enabled: true
  webhook:
    enabled: false
  anonymous:
    enabled: false
authorization:
  mode: "AlwaysAllow"
EOF

systemctl daemon-reload && systemctl enable kubelet && systemctl restart kubelet

2. 生成kubeadm文件

# etcd-1
cat > /tmp/etcd-1.yaml << EOF
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
imageRepository: "192.168.100.198:5000"
etcd:
  local:
    serverCertSANs:
    - "192.168.100.194"
    peerCertSANs:
    - "192.168.100.194"
    extraArgs:
      initial-cluster: etcd1=https://192.168.100.194:2380,etcd2=https://192.168.100.195:2380,etcd3=https://192.168.100.196:2380
      initial-cluster-state: new
      name: etcd1
      listen-peer-urls: https://192.168.100.194:2380
      listen-client-urls: https://192.168.100.194:2379
      advertise-client-urls: https://192.168.100.194:2379
      initial-advertise-peer-urls: https://192.168.100.194:2380
EOF

# etcd-2
cat > /tmp/etcd-2.yaml << EOF
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
imageRepository: "192.168.100.198:5000"
etcd:
  local:
    serverCertSANs:
    - "192.168.100.195"
    peerCertSANs:
    - "192.168.100.195"
    extraArgs:
      initial-cluster: etcd1=https://192.168.100.194:2380,etcd2=https://192.168.100.195:2380,etcd3=https://192.168.100.196:2380
      initial-cluster-state: new
      name: etcd2
      listen-peer-urls: https://192.168.100.195:2380
      listen-client-urls: https://192.168.100.195:2379
      advertise-client-urls: https://192.168.100.195:2379
      initial-advertise-peer-urls: https://192.168.100.195:2380
EOF

# etcd-3
cat > /tmp/etcd-3.yaml << EOF
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
imageRepository: "192.168.100.198:5000"
etcd:
  local:
    serverCertSANs:
    - "192.168.100.196"
    peerCertSANs:
    - "192.168.100.196"
    extraArgs:
      initial-cluster: etcd1=https://192.168.100.194:2380,etcd2=https://192.168.100.195:2380,etcd3=https://192.168.100.196:2380
      initial-cluster-state: new
      name: etcd3
      listen-peer-urls: https://192.168.100.196:2380
      listen-client-urls: https://192.168.100.196:2379
      advertise-client-urls: https://192.168.100.196:2379
      initial-advertise-peer-urls: https://192.168.100.196:2380
EOF
拷贝

scp /tmp/etcd-2.yaml vm-195:/tmp
scp /tmp/etcd-3.yaml vm-196:/tmp

3. 生成证书

# ca.crt & ca.key
kubeadm init phase certs etcd-ca

# etcd-3
kubeadm init phase certs etcd-server --config=/tmp/etcd-3.yaml
kubeadm init phase certs etcd-peer --config=/tmp/etcd-3.yaml
kubeadm init phase certs etcd-healthcheck-client --config=/tmp/etcd-3.yaml
kubeadm init phase certs apiserver-etcd-client --config=/tmp/etcd-3.yaml
scp -r /etc/kubernetes/pki vm-196:/etc/kubernetes

# etcd-2
find /etc/kubernetes/pki -not -name ca.crt -not -name ca.key -type f -delete

kubeadm init phase certs etcd-server --config=/tmp/etcd-2.yaml
kubeadm init phase certs etcd-peer --config=/tmp/etcd-2.yaml
kubeadm init phase certs etcd-healthcheck-client --config=/tmp/etcd-2.yaml
kubeadm init phase certs apiserver-etcd-client --config=/tmp/etcd-2.yaml
scp -r /etc/kubernetes/pki vm-195:/etc/kubernetes

# etcd-1
find /etc/kubernetes/pki -not -name ca.crt -not -name ca.key -type f -delete

kubeadm init phase certs etcd-server --config=/tmp/etcd-1.yaml
kubeadm init phase certs etcd-peer --config=/tmp/etcd-1.yaml
kubeadm init phase certs etcd-healthcheck-client --config=/tmp/etcd-1.yaml
kubeadm init phase certs apiserver-etcd-client --config=/tmp/etcd-1.yaml

# 查看证书
openssl x509 -in /etc/kubernetes/pki/apiserver-etcd-client.crt -noout -text
openssl x509 -in /etc/kubernetes/pki/etcd/server.crt -noout -text
openssl x509 -in /etc/kubernetes/pki/etcd/healthcheck-client.crt -noout -text
openssl x509 -in /etc/kubernetes/pki/etcd/peer.crt -noout -text

需要有以下信息
Subject: O=system:masters, CN=....

X509v3 Subject Alternative Name: 
  DNS:localhost, DNS:vm-194, IP Address:192.168.100.1914 IP Address:127.0.0.1, IP Address:0:0:0:0:0:0:0:1, IP Address:192.168.100.195

4. 生成etcd静态pod配置文件

# 194
kubeadm init phase etcd local --config=/tmp/etcd-1.yaml 

# 195
kubeadm init phase etcd local --config=/tmp/etcd-2.yaml 

# 196
kubeadm init phase etcd local --config=/tmp/etcd-3.yaml 

cat /etc/kubernetes/manifests/etcd.yaml

4. 运行etcd集群

# 194
docker run -d -p 2379:2379 -p 2380:2380 -v /var/lib/etcd:/etcd-data -v /etc/kubernetes/pki/etcd:/etc/kubernetes/pki/etcd \
--name etcd 192.168.100.198:5000/etcd:3.5.0-0 \
/usr/local/bin/etcd \
    --advertise-client-urls=https://192.168.100.194:2379 \
    --cert-file=/etc/kubernetes/pki/etcd/server.crt \
    --client-cert-auth=true \
    --data-dir=/var/lib/etcd \
    --initial-advertise-peer-urls=https://192.168.100.194:2380 \
    --initial-cluster=etcd1=https://192.168.100.194:2380,etcd2=https://192.168.100.195:2380,etcd3=https://192.168.100.196:2380 \
    --initial-cluster-state=new \
    --key-file=/etc/kubernetes/pki/etcd/server.key \
    --listen-client-urls=https://0.0.0.0:2379 \
    --listen-metrics-urls=http://127.0.0.1:2381 \
    --listen-peer-urls=https://0.0.0.0:2380 \
    --name=etcd1 \
    --peer-cert-file=/etc/kubernetes/pki/etcd/peer.crt \
    --peer-client-cert-auth=true \
    --peer-key-file=/etc/kubernetes/pki/etcd/peer.key \
    --peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt \
    --snapshot-count=10000 \
    --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt

# 195
docker run -d -p 2379:2379 -p 2380:2380 -v /var/lib/etcd:/etcd-data -v /etc/kubernetes/pki/etcd:/etc/kubernetes/pki/etcd \
--name etcd 192.168.100.198:5000/etcd:3.5.0-0 \
/usr/local/bin/etcd \
    --advertise-client-urls=https://192.168.100.195:2379 \
    --cert-file=/etc/kubernetes/pki/etcd/server.crt \
    --client-cert-auth=true \
    --data-dir=/var/lib/etcd \
    --initial-advertise-peer-urls=https://192.168.100.195:2380 \
    --initial-cluster=etcd1=https://192.168.100.194:2380,etcd2=https://192.168.100.195:2380,etcd3=https://192.168.100.196:2380 \
    --initial-cluster-state=new \
    --key-file=/etc/kubernetes/pki/etcd/server.key \
    --listen-client-urls=https://0.0.0.0:2379 \
    --listen-metrics-urls=http://127.0.0.1:2381 \
    --listen-peer-urls=https://0.0.0.0:2380 \
    --name=etcd2 \
    --peer-cert-file=/etc/kubernetes/pki/etcd/peer.crt \
    --peer-client-cert-auth=true \
    --peer-key-file=/etc/kubernetes/pki/etcd/peer.key \
    --peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt \
    --snapshot-count=10000 \
    --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt

# 196
docker run -d -p 2379:2379 -p 2380:2380 -v /var/lib/etcd:/etcd-data -v /etc/kubernetes/pki/etcd:/etc/kubernetes/pki/etcd \
--name etcd 192.168.100.198:5000/etcd:3.5.0-0 \
/usr/local/bin/etcd \
    --advertise-client-urls=https://192.168.100.196:2379 \
    --cert-file=/etc/kubernetes/pki/etcd/server.crt \
    --client-cert-auth=true \
    --data-dir=/var/lib/etcd \
    --initial-advertise-peer-urls=https://192.168.100.196:2380 \
    --initial-cluster=etcd1=https://192.168.100.194:2380,etcd2=https://192.168.100.195:2380,etcd3=https://192.168.100.196:2380 \
    --initial-cluster-state=new \
    --key-file=/etc/kubernetes/pki/etcd/server.key \
    --listen-client-urls=https://0.0.0.0:2379 \
    --listen-metrics-urls=http://127.0.0.1:2381 \
    --listen-peer-urls=https://0.0.0.0:2380 \
    --name=etcd3 \
    --peer-cert-file=/etc/kubernetes/pki/etcd/peer.crt \
    --peer-client-cert-auth=true \
    --peer-key-file=/etc/kubernetes/pki/etcd/peer.key \
    --peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt \
    --snapshot-count=10000 \
    --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt

# test
docker run --rm -it \
  --net host \
  -v /etc/kubernetes:/etc/kubernetes 192.168.100.198:5000/etcd:3.5.0-0 etcdctl \
  --cert /etc/kubernetes/pki/etcd/peer.crt \
  --key /etc/kubernetes/pki/etcd/peer.key \
  --cacert /etc/kubernetes/pki/etcd/ca.crt \
  --endpoints https://192.168.100.194:2379 endpoint health --cluster

四、haproxy & keepalive高可用

1. 建立目录

mkdir -p /etc/{haproxy,keepalived}

for i in 192 193; do ssh vm-$i 'mkdir -p /etc/{haproxy,keepalived}'; done

2. haproxy配置文件

# haproxy 与 kube-api部署同一台物理机,vip端口由6443变为8443

cat > /etc/haproxy/haproxy.cfg << EOF
global
    log        127.0.0.1 local0 info
    maxconn    4000
    daemon
    stats socket /var/lib/haproxy/stats

defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 4000

frontend stats
    bind *:9000
    mode http
    stats enable
    stats uri /stats
    stats hide-version  
    stats auth haproxy:@haproxy 

frontend apiservers
    bind *:8443
    mode tcp
    option tcplog
    default_backend k8s_apiservers

backend k8s_apiservers
    mode tcp
    option ssl-hello-chk
    option log-health-checks
    balance roundrobin
    default-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250 maxqueue 256 weight 100
    server kube-apiserver-1 192.168.100.191:6443 check
    server kube-apiserver-2 192.168.100.192:6443 check
    server kube-apiserver-3 192.168.100.193:6443 check
EOF

for i in 192 193; do scp /etc/haproxy/haproxy.cfg vm-$i:/etc/haproxy; done

2. keepalived配置文件

# 191
cat > /etc/keepalived/keepalived.conf << EOF
global_defs {
  router_id vm-191
}
   
vrrp_script check_haproxy {
  script "/usr/sbin/pidof haproxy"
  interval 2
  weight 2
}

vrrp_instance VI_1 {
  interface eth0
  state MASTER
  advert_int 1
  virtual_router_id 51
  priority 300
  unicast_src_ip 192.168.100.191
  unicast_peer {
    192.168.100.192
    192.168.100.193
  }

  authentication {
    auth_type PASS
    auth_pass Password
  }

  virtual_ipaddress {
    192.168.100.190 dev eth0 label eth0:0
  }

  track_script {
    check_haproxy
  }
}
EOF

# 192
cat > /etc/keepalived/keepalived.conf << EOF
global_defs {
  router_id vm-192
}
   
vrrp_script check_haproxy {
  script "/usr/sbin/pidof haproxy"
  interval 2
  weight 2
}

vrrp_instance VI_1 {
  interface eth0
  state BACKUP
  advert_int 1
  virtual_router_id 51
  priority 200
  unicast_src_ip 192.168.100.192
  unicast_peer {
    192.168.100.191
    192.168.100.193
  }

  authentication {
    auth_type PASS
    auth_pass Password
  }

  virtual_ipaddress {
    192.168.100.190 dev eth0 label eth0:0
  }

  track_script {
    check_haproxy
  }
}
EOF

# 193
cat > /etc/keepalived/keepalived.conf << EOF
global_defs {
  router_id vm-193
}
   
vrrp_script check_haproxy {
  script "/usr/sbin/pidof haproxy"
  interval 2
  weight 2
}

vrrp_instance VI_1 {
  interface eth0
  state BACKUP
  advert_int 1
  virtual_router_id 51
  priority 100
  unicast_src_ip 192.168.100.193
  unicast_peer {
    192.168.100.191
    192.168.100.192
  }

  authentication {
    auth_type PASS
    auth_pass Password
  }

  virtual_ipaddress {
    192.168.100.190 dev eth0 label eth0:0
  }

  track_script {
    check_haproxy
  }
}
EOF

4. haproxy静态pod配置文件

cat > /etc/kubernetes/manifests/haproxy.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
  name: haproxy
  namespace: kube-system
spec:
  containers:
  - image: 192.168.100.198:5000/haproxy:2.4.7
    name: haproxy
    livenessProbe:
      failureThreshold: 8
      httpGet:
        host: localhost
        path: /healthz
        port: 6443
        scheme: HTTPS
    volumeMounts:
    - mountPath: /usr/local/etc/haproxy/haproxy.cfg
      name: haproxyconf
      readOnly: true
  hostNetwork: true
  volumes:
  - hostPath:
      path: /etc/haproxy/haproxy.cfg
      type: FileOrCreate
    name: haproxyconf
status: {}
EOF

for i in {192..193}; do scp /etc/kubernetes/manifests/haproxy.yaml vm-$i:/etc/kubernetes/manifests; done

5. keepalived静态pod配置文件

cat > /etc/kubernetes/manifests/keepalived.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  name: keepalived
  namespace: kube-system
spec:
  containers:
  - image: 192.168.100.198:5000/keepalived:2.0.20
    name: keepalived
    resources: {}
    securityContext:
      capabilities:
        add:
        - NET_ADMIN
        - NET_BROADCAST
        - NET_RAW
    volumeMounts:
    - mountPath: /usr/local/etc/keepalived/keepalived.conf
      name: config
  hostNetwork: true
  volumes:
  - hostPath:
      path: /etc/keepalived/keepalived.conf
    name: config
status: {}
EOF

for i in {192..193}; do scp /etc/kubernetes/manifests/keepalived.yaml vm-$i:/etc/kubernetes/manifests; done

6. 测试

docker run --rm -it \
 -p 6443:6443 -p 9000:9000 \
 -v /etc/haproxy:/usr/local/etc/haproxy:ro \
 --name haproxy 192.168.100.198:5000/haproxy:2.4.7 \
 haproxy -f /usr/local/etc/haproxy/haproxy.cfg

docker run --rm -it \
 --privileged --cap-add=NET_ADMIN --net=host \
 -v /etc/keepalived/keepalived.conf:/usr/local/etc/keepalived/keepalived.conf \
 --name keepalived 192.168.100.198:5000/keepalived:2.0.20 \
 /bin/bash

五、kubernetes集群

1. 生成配置文件模板

# kubeadm config print init-defaults > /tmp/kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta2
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 1.2.3.4
  bindPort: 6443
nodeRegistration:
  criSocket: /var/run/dockershim.sock
  imagePullPolicy: IfNotPresent
  name: node
  taints: null
---
apiServer:
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: k8s.gcr.io
kind: ClusterConfiguration
kubernetesVersion: 1.22.0
networking:
  dnsDomain: cluster.local
  serviceSubnet: 10.96.0.0/12
scheduler: {}

2. 下载镜像

# kubeadm config images list
I1022 21:37:02.082274   13564 version.go:254] remote version is much newer: v1.22.3; falling back to: stable-1.21
k8s.gcr.io/kube-apiserver:v1.21.6
k8s.gcr.io/kube-controller-manager:v1.21.6
k8s.gcr.io/kube-scheduler:v1.21.6
k8s.gcr.io/kube-proxy:v1.21.6
k8s.gcr.io/pause:3.4.1
k8s.gcr.io/etcd:3.4.13-0
k8s.gcr.io/coredns/coredns:v1.8.0

kubeadm config images pull --image-repository 192.168.100.198:5000

3. 生成配置文件

# haproxy 与 kube-api部署同一台物理机,vip端口由6443变为8443
cat > /tmp/kubeadm-config.yaml << EOF
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: 1.21.6
controlPlaneEndpoint: "192.168.100.190:8443"
networking:
  podSubnet: "10.240.0.0/16"
imageRepository: "192.168.100.198:5000"
etcd:
  external:
    endpoints:
    - https://192.168.100.194:2379
    - https://192.168.100.195:2379
    - https://192.168.100.196:2379
    caFile: /etc/kubernetes/pki/etcd/ca.crt
    certFile: /etc/kubernetes/pki/apiserver-etcd-client.crt
    keyFile: /etc/kubernetes/pki/apiserver-etcd-client.key
EOF

4. 部署

# 191
scp -r vm-194:/etc/kubernetes/pki /etc/kubernetes

kubeadm init --config /tmp/kubeadm-config.yaml --upload-certs --ignore-preflight-errors=all -v=5

# 成功提示
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/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

You can now join any number of the control-plane node running the following command on each as root:

  kubeadm join 192.168.100.190:8443 --token u0ec4z.88xa15kogx7bk3d8 \
	--discovery-token-ca-cert-hash sha256:049bde6141c319fdea48f8dd7d63320319fa736a6b24de07e102aea03cef764c \
	--control-plane --certificate-key cbd771f88a7d40478a530343243e69f586f8e927a9dbd5cda2f97301205f1eff

Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use
"kubeadm init phase upload-certs --upload-certs" to reload certs afterward.

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.100.190:8443 --token u0ec4z.88xa15kogx7bk3d8 \
	--discovery-token-ca-cert-hash sha256:049bde6141c319fdea48f8dd7d63320319fa736a6b24de07e102aea03cef764c 

5. 配置用户环境

# 191
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config

# 查看pod
kubectl get pods --all-namespaces -o wide

6. 添加控制和工作节点

# 192 & 193
  kubeadm join 192.168.100.190:8443 --token u0ec4z.88xa15kogx7bk3d8 \
	--discovery-token-ca-cert-hash sha256:049bde6141c319fdea48f8dd7d63320319fa736a6b24de07e102aea03cef764c \
	--control-plane --certificate-key cbd771f88a7d40478a530343243e69f586f8e927a9dbd5cda2f97301205f1eff \
  --ignore-preflight-errors=all 

# 197 & 207 & 208
kubeadm join 192.168.100.190:8443 --token u0ec4z.88xa15kogx7bk3d8 \
	--discovery-token-ca-cert-hash sha256:049bde6141c319fdea48f8dd7d63320319fa736a6b24de07e102aea03cef764c \
  --ignore-preflight-errors=all 

# 查看node
kubectl get nodes -o wide

7. 安装flannel网络插件(master)

curl -k https://raw.fastgit.org/flannel-io/flannel/master/Documentation/kube-flannel.yml -o /tmp/kube-flannel.yml

sed -e 's|image: quay.io|image: 192.168.100.198:5000|g' \
    -e 's|image: rancher|image: 192.168.100.198:5000/rancher|g' \
    -i /tmp/kube-flannel.yml

kubectl apply -f /tmp/kube-flannel.yml

8. 更换Calico网络插件(master)

kubectl delete -f /tmp/kube-flannel.yml

curl -k https://docs.projectcalico.org/manifests/calico.yaml -o /tmp/calico.yaml

# pod network cidr = 10.240.0.0/16
sed -e 's|# - name: CALICO_IPV4POOL_CIDR|- name: CALICO_IPV4POOL_CIDR|g' \
    -e 's|#   value: "192.168.0.0/16"|  value: "10.240.0.0/16"|g' \
    -e 's|image: docker.io|image: 192.168.100.198:5000|g' \
    -e 's|:v3.21.0|:v3.20.2|g' \
    -i /tmp/calico.yaml 

kubectl apply -f /tmp/calico.yaml 

curl  -k https://docs.projectcalico.org/manifests/calicoctl.yaml -o /tmp/calicoctl.yaml

sed -e 's|image: calico|image: 192.168.100.198:5000/calico|g' -i /tmp/calicoctl.yaml

kubectl apply -f /tmp/calicoctl.yaml

8. 检查集群状态

# kubectl get pod -A -o wide
NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE     IP                NODE     NOMINATED NODE   READINESS GATES
kube-system   calico-kube-controllers-6c6cd485bd-mm77l   1/1     Running   0          29s     10.240.234.1      vm-193   <none>           <none>
kube-system   calico-node-q76bf                          0/1     Running   0          29s     192.168.100.191   vm-191   <none>           <none>
kube-system   calico-node-qdt62                          0/1     Running   0          30s     192.168.100.192   vm-192   <none>           <none>
kube-system   calico-node-r2cjd                          0/1     Running   0          29s     192.168.100.193   vm-193   <none>           <none>
kube-system   calico-node-ssdxc                          0/1     Running   0          30s     192.168.100.197   vm-197   <none>           <none>
kube-system   calico-node-vw8nv                          0/1     Running   0          29s     192.168.100.207   vm-207   <none>           <none>
kube-system   coredns-c86fdc858-b6gpk                    1/1     Running   0          6m8s    10.240.2.129      vm-197   <none>           <none>
kube-system   coredns-c86fdc858-xxl86                    1/1     Running   0          6m8s    10.240.2.130      vm-197   <none>           <none>
kube-system   haproxy-vm-191                             1/1     Running   0          6m10s   192.168.100.191   vm-191   <none>           <none>
kube-system   haproxy-vm-192                             1/1     Running   0          4m33s   192.168.100.192   vm-192   <none>           <none>
kube-system   haproxy-vm-193                             1/1     Running   0          4m26s   192.168.100.193   vm-193   <none>           <none>
kube-system   keepalived-vm-191                          1/1     Running   0          6m10s   192.168.100.191   vm-191   <none>           <none>
kube-system   keepalived-vm-192                          1/1     Running   0          4m33s   192.168.100.192   vm-192   <none>           <none>
kube-system   keepalived-vm-193                          1/1     Running   0          4m25s   192.168.100.193   vm-193   <none>           <none>
kube-system   kube-apiserver-vm-191                      1/1     Running   0          6m10s   192.168.100.191   vm-191   <none>           <none>
kube-system   kube-apiserver-vm-192                      1/1     Running   0          4m34s   192.168.100.192   vm-192   <none>           <none>
kube-system   kube-apiserver-vm-193                      1/1     Running   0          4m25s   192.168.100.193   vm-193   <none>           <none>
kube-system   kube-controller-manager-vm-191             1/1     Running   0          6m10s   192.168.100.191   vm-191   <none>           <none>
kube-system   kube-controller-manager-vm-192             1/1     Running   0          4m33s   192.168.100.192   vm-192   <none>           <none>
kube-system   kube-controller-manager-vm-193             1/1     Running   0          4m25s   192.168.100.193   vm-193   <none>           <none>
kube-system   kube-proxy-7tlwx                           1/1     Running   0          4m4s    192.168.100.197   vm-197   <none>           <none>
kube-system   kube-proxy-88hf7                           1/1     Running   0          4m26s   192.168.100.193   vm-193   <none>           <none>
kube-system   kube-proxy-gpsb9                           1/1     Running   0          6m8s    192.168.100.191   vm-191   <none>           <none>
kube-system   kube-proxy-w5qdh                           1/1     Running   0          4m34s   192.168.100.192   vm-192   <none>           <none>
kube-system   kube-proxy-zhqn5                           1/1     Running   0          3m1s    192.168.100.207   vm-207   <none>           <none>
kube-system   kube-scheduler-vm-191                      1/1     Running   0          6m10s   192.168.100.191   vm-191   <none>           <none>
kube-system   kube-scheduler-vm-192                      1/1     Running   0          4m33s   192.168.100.192   vm-192   <none>           <none>
kube-system   kube-scheduler-vm-193                      1/1     Running   0          4m25s   192.168.100.193   vm-193   <none>           <none>

# kubectl get node -A -o wide
NAME     STATUS   ROLES                  AGE     VERSION   INTERNAL-IP       EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION           CONTAINER-RUNTIME
vm-191   Ready    control-plane,master   6m24s   v1.22.2   192.168.100.191   <none>        CentOS Linux 7 (Core)   3.10.0-1160.el7.x86_64   docker://20.10.9
vm-192   Ready    control-plane,master   4m42s   v1.22.2   192.168.100.192   <none>        CentOS Linux 7 (Core)   3.10.0-1160.el7.x86_64   docker://20.10.9
vm-193   Ready    control-plane,master   4m34s   v1.22.2   192.168.100.193   <none>        CentOS Linux 7 (Core)   3.10.0-1160.el7.x86_64   docker://20.10.9
vm-197   Ready    <none>                 4m11s   v1.22.2   192.168.100.197   <none>        CentOS Linux 7 (Core)   3.10.0-1160.el7.x86_64   docker://20.10.9
vm-207   Ready    <none>                 3m9s    v1.22.2   192.168.100.207   <none>        CentOS Linux 7 (Core)   3.10.0-1160.el7.x86_64   docker://20.10.9

# kubectl get service -A -o wide
NAMESPACE     NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE     SELECTOR
default       kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP                  9m38s   <none>
kube-system   kube-dns     ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   9m27s   k8s-app=kube-dns

# kubectl get deployment -A -o wide
NAMESPACE     NAME                      READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS                IMAGES                                                 SELECTOR
kube-system   calico-kube-controllers   1/1     1            1           3m50s   calico-kube-controllers   192.168.100.198:5000/calico/kube-controllers:v3.20.2   k8s-app=calico-kube-controllers
kube-system   coredns                   2/2     2            2           9m34s   coredns                   192.168.100.198:5000/coredns:v1.8.4                    k8s-app=kube-dns

# kubectl cluster-info
Kubernetes control plane is running at https://192.168.100.190:8443
CoreDNS is running at https://192.168.100.190:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

9. 测试dns

# kubectl run busybox --image=192.168.100.198:5000/busybox:1.28 --rm=true --restart=Never -it -- nslookup kubernetes
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      kubernetes
Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local
pod "busybox" deleted

# kubectl run busybox --image=192.168.100.198:5000/busybox:1.28 --rm=true --restart=Never -it -- nslookup kube-dns.kube-system
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      kube-dns.kube-system
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
pod "busybox" deleted
posted on 2021-10-21 10:56  北京涛子  阅读(541)  评论(0编辑  收藏  举报