一、前菜:需要掌握的基础知识

1、k8s系统架构

从系统架构来看,k8s分为2种节点:

  • Master 控制节点,做为指挥官;
  • Node 工作节点,干活的

Master节点组成

img
master节点组成:

  • Etcd:Kubernetes集群的数据库
    所有持久化的状态信息存储在Etcd中

  • API Server :提供k8s API接口
    主要处理Rest操作以及更新Etcd中的对象
    是所有资源增删改查的唯一入口。

  • Scheduler:资源调度器
    根据etcd里的节点资源状态决定将Pod绑定到哪个Node上

  • Controller Manager
    负责保障pod的健康存在
    资源对象的自动化控制中心,Kubernetes集群有很多控制器。

  • API相当于命令,沟通API server

Node节点的组成

node节点组成

  • Docker Engine
    负责节点容器的管理工作,最终创建出来的是一个Docker容器。

  • kubelet
    安装在Node上的代理服务,用来管理Pods以及容器/镜像/Volume等,实现对集群对节点的管理。

  • kube-proxy
    安装在Node上的网络代理服务,提供网络代理以及负载均衡,实现与Service通讯。

2、k8s逻辑架构

从逻辑架构上看,k8s分为Pod、Controller、Service 。

POD

  • POD是k8s的最小单位
  • POD的IP地址是随机的,删除POD会改变IP
  • POD都有一个根容器
  • 一个POD内可以由一个或多个容器组成
  • 一个POD内的容器共享根容器的网络命名空间
  • 一个POD内的网络地址由根容器提供

Controller

用来管理POD。控制器的种类有很多:

  • RC Replication Controller:控制POD有多个副本
  • RS ReplicaSet:RC控制的升级版
  • Deployment:推荐使用,功能更强大,包含了RS控制器
  • DaemonSet:保证所有的Node上有且只有一个Pod在运行
  • StatefulSet:有状态的应用,为Pod提供唯一的标识,它可以保证部署和scale的顺序

Service

理解三个不同的ip:NodeIP、CluterIP、POD IP。
img

二、正餐:如何搭建并使用K8S

1、k8s安装

涉及的命令

ipvsadm -Ln			#查看ipvs规则
kubectl get pod			#查看pod信息
kubectl get pod -o wide		#查看pod的详细信息 ip labels
kubectl get pod -n kube-system -o wide	#指定查看某个命名空间的pod的详细信息 
kubectl get nodes		#查看节点信息
kubectl get nodes -o wide	#查看节点详细信息

kubectl -n kube-system edit cm kube-proxy 	#编辑某个资源的配置文件
kubectl -n kube-system logs -f kube-proxy-7cdbn #查看指定命名空间里的指定pod的日志


kubectl create -f kube-flannel.yml 	#根据资源配置清单创建相应的资源
kubectl delete -f kube-flannel.yml   	#删除资源配置清单相应的资源

kubeadm reset 			#重置kubeadm节点
kubeadm token create --print-join-command	#打印出node节点加入master节点的命令
kubeadm join 192.168.159.101:6443 --token uqf018.mia8v3i1zcai19sj     --discovery-token-ca-cert-hash sha256:e7d36e1fb53e59b12f0193f4733edb465d924321bcfc055f801cf1ea59d90aae  #node节点加入master的命令

Kubeadm 是一个工具,它提供了 kubeadm init 以及 kubeadm join 这两个命令来快速创建 kubernetes 集群。

实验环境准备

主机信息如下,系统均采用Centos7.x。

IP地址主机名内存CPU说明
192.168.159.101master14G2主要控制节点也是部署节点
192.168.159.102node12G1应用程序工作节点
192.168.159.103node22G1应用程序工作节点

初始化操作:

  • 所有节点关闭防火墙和SELinux
$ systemctl stop firewalld && systemctl disable firewalld
$ setenforce 0
$ vi /etc/selinux/config
SELINUX=disabled
  • 所有节点需要设定/etc/host解析到所有主机
vi /etc/hosts
192.168.159.101 master1
192.168.159.102 node1
192.168.159.103 node2
  • 配置时间同步定时任务
  # 使用公共NTP网络时间服务器地址:阿里云
  * * * * * /sbin/ntpdate time1.aliyun.com > /dev/null 2>&1
  • 临时关闭swap分区
  swapoff -a
  # 永久关闭
  sed -ri 's/.*swap.*/#&/' /etc/fstab

安装部署docker

#1.设置国内YUM
cd /etc/yum.repos.d/
yum install wget
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

#2.安装指定的docker版本
yum -y install docker-ce-18.09.7-3.el7 docker-ce-cli-18.09.7

#3.设置docker使用阿里云加速
mkdir /etc/docker
cat > /etc/docker/daemon.json <<EOF
    {
      "registry-mirrors": ["https://ig2l319y.mirror.aliyuncs.com"],
      "exec-opts": ["native.cgroupdriver=systemd"]
    }
EOF

#4.启动后台进程
systemctl enable docker && systemctl start docker

#5.查看docker版本
docker -v

部署kubeadm和kubelet

#部署kubeadm和kubelet

#注意!所有机器都需要操作!!!
#注意!所有机器都需要操作!!!
#注意!所有机器都需要操作!!!

#1.设置k8s国内yum仓库
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=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF


#2.安装kubeadm
yum install -y kubelet-1.16.2 kubeadm-1.16.2 kubectl-1.16.2 ipvsadm

#3.设置k8s禁止使用swap
cat > /etc/sysconfig/kubelet<<EOF
KUBELET_CGROUP_ARGS="--cgroup-driver=systemd"
KUBELET_EXTRA_ARGS="--fail-swap-on=false"
EOF

#4.设置内核参数
cat >  /etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF

sysctl --system

#5、修改kubelet:
mkdir /var/lib/kubelet

cat > /var/lib/kubelet/config.yaml <<EOF
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd
EOF

#6.设置kubelet开机启动
systemctl enable kubelet && systemctl start kubelet

#7.加载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 +x /etc/sysconfig/modules/ipvs.modules
source /etc/sysconfig/modules/ipvs.modules
lsmod | grep -e ip_vs -e nf_conntrack_ipv

kubelet启动异常时通过如下命令查看

journalctl -xefu kubelet

master节点初始化

#1.初始化命令
https://v1-16.docs.kubernetes.io/zh/docs/reference/setup-tools/kubeadm/kubeadm-init/

#注意!只在master1节点运行!!!
#注意!只在master1节点运行!!!
#注意!只在master1节点运行!!!

kubeadm init \
--apiserver-advertise-address=192.168.159.101 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.16.2 \
--service-cidr=10.1.0.0/16 \
--pod-network-cidr=10.2.0.0/16 \
--service-dns-domain=cluster.local \
--ignore-preflight-errors=Swap \
--ignore-preflight-errors=NumCPU

#执行完成后会有输出,这是node节点加入k8s集群的命令
===============================================
kubeadm join 192.168.159.101:6443 --token rsl3w2.jdc4tqfb02u243hq \
    --discovery-token-ca-cert-hash sha256:bd318509bc7abc094bccbb67ed2dd2570d8f084cb8d60ad4900b68822225a1e3  
===============================================

#2.为kubectl准备kubeconfig
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

#3.获取node节点信息
[root@master1 ~]# kubectl get nodes
NAME      STATUS     ROLES    AGE   VERSION
master1   NotReady   master   12m   v1.16.2

#4.支持命令补全
yum install bash-completion -y
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
kubectl completion bash >/etc/bash_completion.d/kubectl

#5.设置kube-proxy使用ipvs模式
#执行命令,然后将mode: ""修改为mode: "ipvs"然后保存退出
kubectl edit cm kube-proxy -n kube-system

#重启kube-proxy
kubectl get pod -n kube-system |grep kube-proxy |awk '{system("kubectl delete pod "$1" -n kube-system")}'

#查看pod信息
kubectl get -n kube-system pod|grep "kube-proxy" 
#输出信息:
kube-proxy-f5l4f               1/1     Running   0          5s

#检查日志,如果出现IPVS rr就表示成功
[root@master1 ~]# kubectl -n kube-system logs -f kube-proxy-f5l4f 此处需要替换实例名称
I0806 04:09:12.996082       1 node.go:135] Successfully retrieved node IP: 192.168.159.101
I0806 04:09:12.996124       1 server_others.go:176] Using ipvs Proxier.
W0806 04:09:12.996348       1 proxier.go:420] IPVS scheduler not specified, use rr by default

#检查IPVS规则
[root@master1 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.1.0.1:443 rr
  -> 10.0.0.11:6443               Masq    1      0          0         
TCP  10.1.0.10:53 rr
TCP  10.1.0.10:9153 rr
UDP  10.1.0.10:53 rr

master部署网络插件

#部署网络插件
#1.部署Flannel网络插件
cd /home
yum install git
# 修改全局提交缓存大小
git config --global http.postBuffer 524288000
# 修改全局下载最低速度以及对应的最长时间
git config --global http.lowSpeedLimit 0
git config --global http.lowSpeedTime 999999
# 下载
git clone --depth 1 https://github.com/coreos/flannel.git

#2.修改资源配置清单
yum install vim
cd /home/flannel/Documentation
vim kube-flannel.yml
128:      "Network": "10.2.0.0/16",
189 args参数下:        - --iface=ens33   #新增加

docker pull quay.io/coreos/flannel:v0.14.0

#3.应用资源配置清单
kubectl create -f kube-flannel.yml

#4.检查pod运行状态,等一会应该全是running
[root@master1 ~]# kubectl -n kube-system get pod
NAME                            READY   STATUS    RESTARTS   AGE
coredns-58cc8c89f4-gjh44          1/1     Running   0          133m
coredns-58cc8c89f4-thvn8          1/1     Running   0          133m
etcd-master1                      1/1     Running   0          132m
kube-apiserver-master1            1/1     Running   0          132m
kube-controller-manager-master1   1/1     Running   0          132m
kube-flannel-ds-7b2sb             1/1     Running   0          3m23s
kube-proxy-xc468                  1/1     Running   0          119m
kube-scheduler-master1            1/1     Running   1          132m

报错时查看日志:

kubectl logs kube-flannel-ds-ddbfs -n kube-system

flannel配置出错时修改

先执行 kubectl delete -f kube-flannel.yml

再修改配置文件

最后再次执行  kubectl create -f kube-flannel.yml

node节点部署

1.在master节点上输出增加节点的命令
kubeadm token create --print-join-command

输出:
kubeadm join 192.168.159.101:6443 --token o7xa1t.yh61s7p15rawuxju     --discovery-token-ca-cert-hash sha256:bd318509bc7abc094bccbb67ed2dd2570d8f084cb8d60ad4900b68822225a1e3 
 
2.在node1和node2节点执行加入集群的命令(token取第一步中)
kubeadm join 192.168.159.101:6443 --token o7xa1t.yh61s7p15rawuxju     --discovery-token-ca-cert-hash sha256:bd318509bc7abc094bccbb67ed2dd2570d8f084cb8d60ad4900b68822225a1e3 

3.在master1节点上查看状态
kubectl get nodes

4.给其他节点打标签
kubectl label nodes node1 node-role.kubernetes.io/node=
kubectl label nodes node2 node-role.kubernetes.io/node=

5.再次查看节点状态
[root@node1 ~]# kubectl get nodes
NAME    STATUS   ROLES    AGE    VERSION
master1   Ready    master   171m   v1.16.2
node1   Ready    node     27m    v1.16.2
node2   Ready    node     27m    v1.16.2

如果节点一直处于NotReady状态,则通过以下命令查看异常

kubectl describe nodes node1
# 查看kubelet日志
journalctl -e -u kubelet

安装k8s控制台

1.项目GitHub: https://github.com/kubernetes/dashboard

2.下载dashboard配置文件

wget https://raw.githubusercontents.com/kubernetes/dashboard/v2.0.1/aio/deploy/recommended.yaml

3.修改yaml文件
新增type: NodePort 和 nodePort:31443,以便能实现非本机访问

   kind: Service
      apiVersion: v1
      metadata:
        labels:
          k8s-app: kubernetes-dashboard
        name: kubernetes-dashboard
        namespace: kubernetes-dashboard
      spec:
        type: NodePort
        ports:
          - port: 443
            targetPort: 8443
            nodePort: 31443
        selector:
          k8s-app: kubernetes-dashboard 

安装

  kubectl apply -f recommended.yaml

4.创建认证令牌(RBAC)
创建一个admin-user

mkdir /home/kubernetes-dashboard
cat > /home/kubernetes-dashboard/dashboard-adminuser.yaml <<EOF
  apiVersion: v1
  kind: ServiceAccount
  metadata:
    name: admin-user
    namespace: kubernetes-dashboard
EOF

kubectl apply -f /home/kubernetes-dashboard/dashboard-adminuser.yaml 

创建一个集群角色

cat > /home/kubernetes-dashboard/dashboard-ClusterRoleBinding.yaml <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kubernetes-dashboard
EOF

kubectl apply -f /home/kubernetes-dashboard/dashboard-ClusterRoleBinding.yaml

输出结果

clusterrolebinding.rbac.authorization.k8s.io/admin-user created

获取token
执行命令:

kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')

显示如下:

Name:         admin-user-token-tjmrw
Namespace:    kubernetes-dashboard
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: admin-user
              kubernetes.io/service-account.uid: 2cda32e8-d69b-40fb-90a4-224fd58edaf1

Type:  kubernetes.io/service-account-token

Data
====
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IkcyUWduTE55a3hrWjctdEJKeEUyMzJjQmhDd3VIQ0VtYVJqbUtaY2E5OEkifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyLXRva2VuLXJzbGhsIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJkMTE1YWZiYS0wMzMyLTQ0MzItOTAwOC0wYzk1ZjNlYzZjZmEiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZXJuZXRlcy1kYXNoYm9hcmQ6YWRtaW4tdXNlciJ9.1s9FVIuPf2hFKTWGjJDLgJ0U7dqYu5Ne7TAJaEqUcWYKyy02o9Xdacq1TUVOv9fbRHhYHbcLxJVghYmlYjUWrFU-yI3hDFUYZwcG-cFYYhQew6_aZe4QsMG8s77gYIx0NItWJYBpVzTILhUZ4onSbi02Hql8ssvSwM-vQMSKKKcWMKGbFEwvRDQkkJ3zYv6SEqBvlh5Rg3tGqhCGTW8cVvHxUH29NqaQzQxzedR0wQKAzJP2ZFti8RxDskKxSQ7JvzUJlPcbSn0gN4YN51XuAO3JNLwvBqKlJ33zjwddEzAQeVo8W5Nxdb0fpfP3zqIcn02Mx7pUyzRexPdGtO-5hQ
ca.crt:     1025 bytes
namespace:  20 bytes

匿名用户授权

kubectl create clusterrolebinding test:anonymous --clusterrole=cluster-admin --user=system:anonymous

5.访问k8s集群UI

https://192.168.159.101:31443 

img
输入刚才获取的 token

6.验证:部署nginx
配置
在这里插入图片描述
创建成功后
在这里插入图片描述
访问
在这里插入图片描述

2、harbor部署

Docker容器应用的开发和运行离不开可靠的镜像管理,虽然Docker官方也提供了公共的镜像仓库,但是从安全和效率等方面考虑,部署私有环境内的Registry也是非常必要的。Harbor是由VMware公司开源的企业级的Docker Registry管理项目。
img

1.学习目标
学习部署k8s私有镜像仓库harbor。

2.在master上安装harbor
下载地址
https://github.com/goharbor/harbor/releases

cd /opt/
# 上传harbor安装包
yum install lrzsz
rz   
tar zxf harbor-offline-installer-v1.10.1.tgz
cd harbor/

3.编辑harbor配置文件

vim harbor.yml

hostname: 192.168.159.101
port: 8888
harbor_admin_password: 123456
data_volume: /data/harbor

服务器若无https证书,则需要注释掉文件中的https协议内容

4.执行安装

yum install docker-compose -y
./install.sh

如果docker-compose版本过低,可以用如下方式升级ocker-compose

下载docker-compose

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

添加docker-compose运行权限

sudo chmod +x /usr/local/bin/docker-compose

查看docker-compose版本

docker-compose --version

5.浏览器访问

http://192.168.159.101:8888
admin/123456

6.建立镜像仓库

这里有2种访问级别:

  • 公开:任何人都可以直接访问并下载镜像
  • 私有:登陆授权后才允许下载镜像

如果创建私有仓库,k8s是不能直接下载的,需要配置安全文件。
在这里插入图片描述

7. master的docker开放2375端口

编辑docker 文件

vi /usr/lib/systemd/system/docker.service
在 ExecStart 行最后面加入红框中的内容
-H tcp://0.0.0.0:2375

在这里插入图片描述

8.所有节点都配置docker信任harbor仓库并重启docker

cat >/etc/docker/daemon.json <<EOF
    {
      "registry-mirrors": ["https://ig2l319y.mirror.aliyuncs.com"],
      "exec-opts": ["native.cgroupdriver=systemd"],
      "insecure-registries" : ["http://192.168.159.101:8888"]
    }
EOF

systemctl daemon-reload
systemctl restart docker
###############注意###############
在master上重启docker后,如果harbor不正常了,重启harbor即可
cd /opt/harbor
docker-compose restart 

3、k8s部署springboot应用

制作镜像并上传harbor

使用Maven 打包 springboot应用,并将镜像上传到 Harbor 仓库中,操作步骤如下:

1.maven 配置文件settings.xml加入Harbor的服务信息

<server>
      <!--maven的pom中可以根据这个id找到这个server节点的配置-->  
      <id>docker-harbor</id>
      <username>admin</username>
      <password>123456</password>
	  <configuration>
       <email>zhoujf@ffcs.cn</email>
    </configuration>
</server>

2.在springboot项目的pom.xml文件加入以下配置

<properties>
	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
	<java.version>1.8</java.version>
	<docker.repostory>192.168.159.101:8888</docker.repostory>
	<!--harbor上建的项目的名称-->
	<docker.registry.name>crm</docker.registry.name> 
</properties>

........
	<build>
	<plugins>
		<plugin>
			<groupId>com.spotify</groupId>
			<artifactId>docker-maven-plugin</artifactId>
			<version>1.0.0</version>
			<configuration>
				<imageName>${docker.repostory}/${docker.registry.name}/${project.artifactId}:${project.version}</imageName>
				<!-- 指定Dockerfile所在的路径 -->
			<dockerDirectory>${project.basedir}</dockerDirectory>
			<dockerHost>http://192.168.159.101:2375</dockerHost>
			<resources>
				<resource>
					<targetPath>/</targetPath>
					<directory>${project.build.directory}</directory>
					<include>${project.build.finalName}.jar</include>
				</resource>
			</resources>
			<serverId>docker-harbor</serverId>
			<registryUrl>${docker.repostory}</registryUrl>
			<pushImage>true</pushImage>
		</configuration>
	</plugin>
</plugins>
</build>

3.编写Dockerfile
在项目的根目录下新建Dockerfile文件,内容如下:

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD workplace/target/*jar app.jar
ENTRYPOINT [ "java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app.jar" ]

4.编译并上传

mvn clean package docker:build -e

查看harbor控制台是否有上传的springboot项目的jar包
在这里插入图片描述
在这里插入图片描述

应用部署

登陆k8s控制台,配置应用

在这里插入图片描述

创建成功后
在这里插入图片描述

访问
在这里插入图片描述

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐