1 搭建K8S集群

通过Kubeadm可以便捷地搭建K8S集群,如下所示为具体步骤

1.1 准备虚拟机

首先需要准备三台装有CentOS 7的虚拟机,一个Master两个Slave,对三个节点进行初始化操作

# 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld

# 关闭selinux
# 永久关闭
sed -i 's/enforcing/disabled/' /etc/selinux/config  
# 临时关闭
setenforce 0  

# 关闭swap
# 临时
swapoff -a 
# 永久关闭
sed -ri 's/.*swap.*/#&/' /etc/fstab

# 根据规划设置主机名【master节点上操作】
hostnamectl set-hostname k8smaster
# 根据规划设置主机名【node1节点操作】
hostnamectl set-hostname k8snode1
# 根据规划设置主机名【node2节点操作】
hostnamectl set-hostname k8snode2

# 在master添加hosts
cat >> /etc/hosts << EOF
192.168.177.130 k8smaster
192.168.177.131 k8snode1
192.168.177.132 k8snode2
EOF


# 将桥接的IPv4流量传递到iptables的链
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
# 生效
sysctl --system  

# 通过ntpdate工具进行时间同步
yum install ntpdate -y
ntpdate time.windows.com

1.2、安装组件

分别在三个节点安装 docker kubelet kubeadm kubectl

1.2.1 安装Docker

首先配置一下Docker的阿里yum源

cat >/etc/yum.repos.d/docker.repo<<EOF
[docker-ce-edge]
name=Docker CE Edge - \$basearch
baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/7/\$basearch/edge
enabled=1
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/docker-ce/linux/centos/gpg
EOF

然后yum方式安装docker

# yum安装
yum -y install docker-ce

# 查看docker版本
docker --version  

# 启动docker
systemctl enable docker
systemctl start docker

配置docker的镜像源

cat >> /etc/docker/daemon.json << EOF
{
  "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"]
}
EOF

然后重启docker

systemctl restart docker

1.2.2 安装kubernets

配置yum的k8s软件源

cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

安装kubeadm,kubelet和kubectl,默认安装最新版,这里指定版本号:

# 安装kubelet、kubeadm、kubectl,同时指定版本
yum install -y kubelet-1.18.0 kubeadm-1.18.0 kubectl-1.18.0
# 设置开机启动
systemctl enable kubelet

1.3. 初始化Master节点

在Master(192.168.177.130 ) 执行初始化命令,通过参数指定api server地址、k8s版本、cidr地址等信息,通过--image-repository指定镜像仓库地址

kubeadm init --apiserver-advertise-address=192.168.177.130 --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.18.0 --service-cidr=10.96.0.0/12  --pod-network-cidr=10.244.0.0/16

安装完成后出现如下页面,

kubernetes部署应用 kubernetes安装配置_kubernetes部署应用

按照图中提示进行初始化操作

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

初始化完成后可以查看正在运行的节点

kubectl get nodes

kubernetes部署应用 kubernetes安装配置_nginx_02

能够看到,目前有一个master节点已经运行了,但是还处于未准备状态

1.4 Slave节点加入集群

分别在node1和node2两个节点执行如下操作,将其加入到master集群。该命令是上一步master初始化完成后显示的命令,每个人不一样

kubeadm join 192.168.177.130:6443 --token 8j6ui9.gyr4i156u30y80xf \
    --discovery-token-ca-cert-hash sha256:eda1380256a62d8733f4bddf926f148e57cf9d1a3a58fb45dd6e80768af5a500

当把两个节点都加入进来后,可以在Master节点 执行下面命令查看集群节点情况

kubectl get node

kubernetes部署应用 kubernetes安装配置_docker_03

1.5 安装CNI网络插件

可以看到上面节点的状态还是NotReady,因为需要网络插件来进行联网访问

# 下载网络插件配置
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

默认镜像地址无法访问,sed命令修改为docker hub镜像仓库。

# 添加
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

##①首先下载v0.13.1-rc2-amd64 镜像
##参考博客:
##② 导入镜像,命令,,特别提示,3个机器都需要导入,3个机器都需要导入,3个机器都需要导入,3个机器都需要导入,重要的事情说3遍。不然抱错。如果没有操作,报错后,需要删除节点,重置,在导入镜像,重新加入才行。本地就是这样操作成功的!
docker load < flanneld-v0.13.1-rc2-amd64.docker
#####下载本地,替换将image: quay.io/coreos/flannel:v0.13.1-rc2 替换为 image: quay.io/coreos/flannel:v0.13.1-rc2-amd64

# 查看状态 【kube-system是k8s中的最小单元】
kubectl get pods -n kube-system

运行后的结果

kubernetes部署应用 kubernetes安装配置_nginx_04

运行完成后,我们查看状态可以发现,已经变成了Ready状态了

kubernetes部署应用 kubernetes安装配置_kubernetes_05

下面通过拉取一个nginx对集群进行测试,

# 下载nginx 【会联网拉取nginx镜像】
kubectl create deployment nginx --image=nginx
# 查看状态
kubectl get pod
# 暴露端口
kubectl expose deployment nginx --port=80 --type=NodePort
# 查看一下对外的端口
kubectl get pod,svc

能够看到,我们已经成功暴露了 80端口 到 30529上

kubernetes部署应用 kubernetes安装配置_kubernetes部署应用_06


在宿主机浏览器上,通过master访问30529端口http://192.168.177.130:30529/,可以看到nginx启动页面

2 高可用集群

如果只有一个master节点,当master节点宕机的时,由于master复杂集群管理,所以整个集群将无法提供服务。因此可以通过搭建具有多个master节点的集群实现高可用服务。当一个master挂掉后,其他master节点可以继续工作,保证集群依然可用。

高可用集群的master节点除了之前的apiserver、controller manager、scheduler、网络插件flannel之外,还需要安装额外的两个组件:

  • keepalived:配置虚拟ip,检查节点的状态
  • haproxy:用于多个master之间的负载均衡服务

keepalived会向外暴露一个虚拟IP(VIP)用于访问集群服务,访问到达之后再根据内部IP路由到指定节点。keepalived还会对master节点进行检查,当一个master挂掉之后便会将VIP转移到其他的master节点从而保证集群可用。

如下所示通过master1和master2两个节点实现高可用,使用node1作为工作节点,其IP和虚拟IP规定如下

角色

IP

master1

192.168.44.155

master2

192.168.44.156

node1

192.168.44.157

VIP(虚拟ip)

192.168.44.158

2.1 准备虚拟机

和之前一样,对每个节点进行如下设置

# 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld

# 关闭selinux
sed -i 's/enforcing/disabled/' /etc/selinux/config  # 永久
setenforce 0  # 临时

# 关闭swap
swapoff -a  # 临时
sed -ri 's/.*swap.*/#&/' /etc/fstab    # 永久

# 根据规划设置主机名
hostnamectl set-hostname <hostname>

# 在master添加hosts
cat >> /etc/hosts << EOF
192.168.44.158    master.k8s.io   k8s-vip
192.168.44.155    master01.k8s.io master1
192.168.44.156    master02.k8s.io master2
192.168.44.157    node01.k8s.io   node1
EOF

# 将桥接的IPv4流量传递到iptables的链
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system  # 生效

# 时间同步
yum install ntpdate -y
ntpdate time.windows.com

2.2 安装组件

首先需要按照1.2一样安装docker和k8s相关组件

此外高可用集群还需要额外安装keepalived和haproxy

# keepalived
yum install -y conntrack-tools libseccomp libtool-ltdl
yum install -y keepalived
# haproxy
yum install -y haproxy

按照如下所示对master1和master2进行配置,其中master1作为主节点,优先级高;master2作为备用节点

cat > /etc/keepalived/keepalived.conf <<EOF 
! Configuration File for keepalived

global_defs {
   router_id k8s
}

vrrp_script check_haproxy {
    script "killall -0 haproxy"
    interval 3
    weight -2
    fall 10
    rise 2
}

vrrp_instance VI_1 {
	# 主节点
    state MASTER 
    interface ens33 
    virtual_router_id 51
    # 高优先级
    priority 250
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass ceb1b3ec013d66163d6ab
    }
    virtual_ipaddress {
    	# master1的ip
        192.168.44.158
    }
    track_script {
        check_haproxy
    }

}
EOF

如下所示为master2的配置

cat > /etc/keepalived/keepalived.conf <<EOF 
! Configuration File for keepalived

global_defs {
   router_id k8s
}

vrrp_script check_haproxy {
    script "killall -0 haproxy"
    interval 3
    weight -2
    fall 10
    rise 2
}

vrrp_instance VI_1 {
    state BACKUP 
    interface ens33 
    virtual_router_id 51
    priority 200
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass ceb1b3ec013d66163d6ab
    }
    virtual_ipaddress {
        192.168.44.158
    }
    track_script {
        check_haproxy
    }

}
EOF

如下所示为haproxy的配置,两台master节点的配置均相同,配置中指定了haproxy运行的端口为16443

cat > /etc/haproxy/haproxy.cfg << EOF
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    # to have these messages end up in /var/log/haproxy.log you will
    # need to:
    # 1) configure syslog to accept network log events.  This is done
    #    by adding the '-r' option to the SYSLOGD_OPTIONS in
    #    /etc/sysconfig/syslog
    # 2) configure local2 events to go to the /var/log/haproxy.log
    #   file. A line like the following can be added to
    #   /etc/sysconfig/syslog
    #
    #    local2.*                       /var/log/haproxy.log
    #
    log         127.0.0.1 local2
    
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon 
       
    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------  
defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    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                 3000
#---------------------------------------------------------------------
# kubernetes apiserver frontend which proxys to the backends
#--------------------------------------------------------------------- 
frontend kubernetes-apiserver
    mode                 tcp
    bind                 *:16443
    option               tcplog
    default_backend      kubernetes-apiserver    
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend kubernetes-apiserver
    mode        tcp
    balance     roundrobin
    server      master01.k8s.io   192.168.44.155:6443 check
    server      master02.k8s.io   192.168.44.156:6443 check
#---------------------------------------------------------------------
# collection haproxy statistics message
#---------------------------------------------------------------------
listen stats
    bind                 *:1080
    stats auth           admin:awesomePassword
    stats refresh        5s
    stats realm          HAProxy\ Statistics
    stats uri            /admin?stats
EOF

接下来启动keepalived、haproxy

# 启动keepalived
$ systemctl start keepalived.service
# 设置开机启动
$ systemctl enable keepalived.service
# 查看启动状态
$ systemctl status keepalived.service

# 设置开机启动
$ systemctl enable haproxy
# 开启haproxy
$ systemctl start haproxy
# 查看启动状态
$ systemctl status haproxy

2.3 初始化master节点

在具有vip的主节点master1上启动master

首先编辑配置文件如下

$ mkdir /usr/local/kubernetes/manifests -p
$ cd /usr/local/kubernetes/manifests/
$ vi kubeadm-config.yaml

apiServer:
  certSANs:
    - master1
    - master2
    - master.k8s.io
    - 192.168.44.158
    - 192.168.44.155
    - 192.168.44.156
    - 127.0.0.1
  extraArgs:
    authorization-mode: Node,RBAC
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta1
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controlPlaneEndpoint: "master.k8s.io:16443"
controllerManager: {}
dns: 
  type: CoreDNS
etcd:
  local:    
    dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: v1.16.3
networking: 
  dnsDomain: cluster.local  
  podSubnet: 10.244.0.0/16
  serviceSubnet: 10.1.0.0/16
scheduler: {}

执行如下命令进行初始化

kubeadm init --config kubeadm-config.yaml

命令行会弹出如下提示和加入集群的join命令,执行其中的提示命令

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
$ kubectl get nodes
$ kubectl get pods -n kube-system

kubeadm join master.k8s.io:16443 --token jv5z7n.3y1zi95p952y9p65 \
    --discovery-token-ca-cert-hash sha256:403bca185c2f3a4791685013499e7ce58f9848e2213e27194b75a2e3293d8812 \
    --control-plane

2.4 加入集群

从master1复制密钥及相关文件到master2

# ssh root@192.168.44.156 mkdir -p /etc/kubernetes/pki/etcd

# scp /etc/kubernetes/admin.conf root@192.168.44.156:/etc/kubernetes
   
# scp /etc/kubernetes/pki/{ca.*,sa.*,front-proxy-ca.*} root@192.168.44.156:/etc/kubernetes/pki
   
# scp /etc/kubernetes/pki/etcd/ca.* root@192.168.44.156:/etc/kubernetes/pki/etcd

执行在master1上init后输出的join命令,需要带上参数--control-plane表示把master控制节点加入集群

kubeadm join master.k8s.io:16443 --token ckf7bs.30576l0okocepg8b     --discovery-token-ca-cert-hash sha256:19afac8b11182f61073e254fb57b9f19ab4d798b70501036fc69ebef46094aba --control-plane

同样地在node1节点上执行加入master1:

kubeadm join master.k8s.io:16443 --token ckf7bs.30576l0okocepg8b     --discovery-token-ca-cert-hash sha256:19afac8b11182f61073e254fb57b9f19ab4d798b70501036fc69ebef46094aba

2.5 安装网络插件

操作和1.5类似

3 部署Java应用

如果在开发完成后一个Java应用后,应该如何通过K8S进行部署呢?

3.1 制作镜像

首先通过打包工具将java应用进行打包,这里将打包好的文件上传到服务器的 target/demo.jar

编写dockerfile如下所示,

# 从一个基础镜像作为起点
FROM openjdk:8-jdk-alpine
VOLUME /tmp
# 将本地打包好的文件添加到镜像
ADD ./target/demo.jar demo.jar
# 镜像启动后执行如下命令启动Java应用
ENTRYPOINT ["java","-jar","/demo.jar", "&"]

打包镜像

# 制作镜像
docker build -t java-demo-01:latest .
# 查看镜像
docker images;
# 启动镜像
docker run -d -p 8111:8111 java-demo-01:latest -t

镜像启动后访问master相应端口就可以看见应用http://192.168.177.130:8111/

3.2 镜像仓库

也可将制作好的镜像上传到镜像仓库,这样在任意一个集群都可以拉取镜像并运行项目了

首先我们需要到 阿里云 容器镜像服务,然后开始创建镜像仓库

kubernetes部署应用 kubernetes安装配置_kubernetes部署应用_07

然后选择本地仓库

kubernetes部署应用 kubernetes安装配置_kubernetes部署应用_08

我们点击我们刚刚创建的镜像仓库,就能看到以下的信息

kubernetes部署应用 kubernetes安装配置_容器_09

3.3 推送镜像

使用命令登录

docker login --username=XXXXXXX@163.com registry.cn-shenzhen.aliyuncs.com

然后输入刚刚我们开放时候的注册的密码

为镜像添加版本号

# 实例
docker tag [ImageId] registry.cn-shenzhen.aliyuncs.com/mogublog/java-project-01:[镜像版本号]

# 举例
docker tag 33f11349c27d registry.cn-shenzhen.aliyuncs.com/mogublog/java-project-01:1.0.0

添加版本号信息后,就可以推送我们的镜像到阿里云了

docker push registry.cn-shenzhen.aliyuncs.com/mogublog/java-project-01:1.0.0

在阿里云镜像服务,就能看到推送上来的镜像了

kubernetes部署应用 kubernetes安装配置_kubernetes部署应用_10

3.4 通过K8S部署镜像

在我们推送镜像到服务器后,就可以通过K8S部署镜像仓库中的应用了

首先根据仓库中的镜像导出yaml配置文件

kubectl create deployment  javademo1 --image=registry.cn-
shenzhen.aliyuncs.com/mogublog/java-project-01:1.0.0 --dry-run -o yaml > javademo1.yaml

导出后的 javademo1.yaml 如下所示

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: javademo1
  name: javademo1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: javademo1
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: javademo1
    spec:
      containers:
      - image: registry.cn-shenzhen.aliyuncs.com/mogublog/java-project-01:1.0.0
        name: java-project-01
        resources: {}
status: {}

通过yaml部署应用deployment

kubectl apply -f javademo1.yaml
# 对外暴露端口
kubectl expose deployment javademo1 --port=8111  --target-port=8111 --type=NodePort
# 查看对外端口号
kubectl get svc

kubernetes部署应用 kubernetes安装配置_kubernetes部署应用_11


然后通过下面的地址访问

# 对内访问
curl http://10.106.103.242:8111/user
# 对外访问
http://192.168.177.130:32190/user