MENU

Kubernetes入门:K8S集群基础操作

2019 年 03 月 08 日 • 应用服务器

本篇文章建立在Kubernetes 入门:高可用集群搭建的基础之上,在开始之前在操作节点执行两条命令,以支持kubectl命令tables补全。

[root@master-1 ~]# yum -y install bash-completion
[root@master-1 ~]# kubectl completion bash > ~/.kube/kubectl_autocompletion
[root@master-1 ~]# cat >>~/.bash_profile<<OEF
> if [ -f /usr/local/share/bash-completion/bash_completion ]; then
>   . /usr/local/share/bash-completion/bash_completion
> fi
> 
> source ~/.kube/kubectl_autocompletion
> OEF
[root@master-1 ~]# source .bash_profile 

kubectl命令行管理工具

大概分为三个小节,第一kubectl管理命令概要,第二kubectl管理应用程序和生命周期,第三远程连接K8S集群。先看第一个。

kubectl管理命令概要

用于连接K8S集群和管理资源的命令行工具,也就是通过这个工具,可以完成所有的任务,大概是这些。

管理应用程序生命周期

了解过Swarm的应该都知道,要部署一个应用具体要有那些步骤,其实在k8s里和swarm步骤一样,都是以镜像来创建或更新服务的,只是命令不一样,具体怎么创建一个项目在K8S中,下面实例。

1.创建服务

这里只是简单介绍一下使用kubectl命令行的发布更新回滚流程。

[root@master-1 ~]# kubectl run nginx --replicas=3 --image=nginx:latest --port=80
[root@master-1 ~]# kubectl get pods
NAME                     READY   STATUS    RESTARTS   AGE
nginx-7697996758-7jhf4   1/1     Running   0          8s
nginx-7697996758-qqk2h   1/1     Running   0          8s
nginx-7697996758-vz4sz   1/1     Running   0          8s

创建成功了,很多参数和swarm几乎一样,具体如下。

参数描述
replicas副本数量
--image指定镜像
--port端口

实际上我们用命令创建了一个控制器(deployment),这个控制器负责更高级的功能,譬如滚动更新,管理你的副本,暂时先了解一下,可以看一下。

[root@master-1 ~]# kubectl get deployment
NAME    DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx   3         3         3            3           7m58s

2.发布服务

K8S中,服务不是创建好了就可以访问到的,需要创建一个service把你的服务暴露出去,操作如下。

[root@master-1 ~]# kubectl expose deployment nginx --port=80 --type=NodePort --target-port=80 --name=nginx-service
root@master-1 ~]# kubectl get svc
NAME            TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
kubernetes      ClusterIP   10.0.0.1     <none>        443/TCP        4d2h
nginx-service   NodePort    10.0.0.143   <none>        80:43278/TCP   5m34s
参数描述
deployment指定deployment名字,也就是刚刚创建的nginx
--portservice内部访问端口
--type=NodePort类型为NodePort
--target-port容器端口
--nameservice的名字

现在已经发不出去了,随机的端口为43278,所以访问任意Node节点的43278即可。

3.更新服务

先看一下nginx使用的镜像版本。

[root@master-1 ~]# kubectl describe pod nginx-7697996758-7jhf4 | grep image
  Normal  Pulling    25m   kubelet, node-2    pulling image "nginx:latest"
  Normal  Pulled     25m   kubelet, node-2    Successfully pulled image "nginx:latest"

是最新版本的,现在把他更新成1.15.6的,上图的HTTP响应头也能看到目前版本是1.15.9

[root@master-1 ~]# kubectl set image deployment/nginx nginx=nginx:1.15.6
deployment.extensions/nginx image updated

上面做的事情就是更新nginx服务的image字段为nginx:1.15.6,这就开始更新了,他触发了一个滚动更新,确保业务不中断,确认一下这个镜像是不是1.15.6的。

[root@master-1 ~]# for i in `echo 192.168.1.{202..204}:43278`; do   curl -I $i; done

没问题,已经更新成功了。

4.服务回滚

先查看一下发布过的历史版本

[root@master-1 ~]# kubectl rollout history deployment/nginx 
deployment.extensions/nginx 
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

1就是latest版本,2就是当前版本,要回滚一条命令就好了,指定回滚版本也可以。

[root@master-1 ~]# kubectl rollout undo deployment/nginx
deployment.extensions/nginx

回滚就是做了一个逆向的操作,重新部署一下之前的镜像,也就滚动回滚,再看一下HTTP的响应头,是1.15.9就对了。

回滚成功了,下面就是删除了

5.删除服务

在部署的时候我们主要是部署了两套资源,一套是deployment,一套是service,所以直接把他们两个删掉就行了。

[root@master-1 ~]# kubectl delete deployment/nginx
deployment.extensions "nginx" deleted
[root@master-1 ~]# kubectl delete svc/nginx-service
service "nginx-service" deleted
[root@master-1 ~]# kubectl get pods
No resources found.

没了,大概就是这样,这就是一个完整的生命周期,从创建到删除,现在有了对K8S有一个初步的认识。

kubectl远程连接K8S集群

现在所有的管理都是在Master上进行操作的,kubectl离开了Master他就不行了,因为Master跑了apiserver,而apiserver现在监听的地址是127.0.0.1:8080kubectl默认连接的apiserver的地址就是127.0.0.1:8080看一下。

[root@master-1 ~]# netstat -lntp | grep apiserve
tcp        0      0 192.168.1.200:6443      0.0.0.0:*               LISTEN      21641/kube-apiserve 
tcp        0      0 127.0.0.1:8080          0.0.0.0:*               LISTEN      21641/kube-apiserve 

现在想在别的非Master节点连接K8S集群,具体的方法是生成一个名为kubectl config的配置文件,这个配置文件包含了连接apiserver的认证信息,现在我想在负载均衡节点访问K8S集群,操作如下。

复制文件

先把kubectl传到负载均衡两个节点。

[root@master-1 ~]# ansible loadbalancer -m copy -a "src=/usr/local/kubernetes/bin/kubectl dest=/usr/local/bin/ mode=755"

生成配置文件

Master节点操作,上脚本吧

#!/bin/bash
KUBE_APISERVER=$1
SSL_DIR=$2


kubectl config set-cluster kubernetes \
  --server=${KUBE_APISERVER} \
  --certificate-authority=$SSL_DIR/ca.pem \
  --embed-certs=true \
  --kubeconfig=config


kubectl config set-credentials cluster-admin \
  --certificate-authority=$SSL_DIR/ca.pem \
  --embed-certs=true \
  --client-key=$SSL_DIR/admin-key.pem \
  --client-certificate=$SSL_DIR/admin.pem \
  --kubeconfig=config
  
kubectl config set-context default --cluster=kubernetes \
  --user=cluster-admin \
  --kubeconfig=config \

kubectl config use-context default --kubeconfig=config 

传入两个参数,一个是apiserver的地址,我有负载均衡器,所以直接写VIP了,也就是207,证书位置行传入,开始执行。

[root@master-1 /usr/local/kubernetes/script]# sh kubectl-cluster.sh https://192.168.1.207:6443 /usr/local/kubernetes/ssl/

执行后会在当前目录生成一个config文件,然后把这个文件传到两个负载均衡节点上,然后去试试执行一下。

测试能否正常连接

[root@master-1 ~]# ansible loadbalancer -m file -a "path=/root/.kube state=directory"
[root@master-1 /usr/local/kubernetes/script]# ansible loadbalancer -m copy -a "src=./config dest=/root/.kube"
[root@master-1 ~]# ssh loadbalancer-1 
Last login: Mon Mar  4 18:37:39 2019 from 192.168.1.200
[root@loadbalancer-1 ~]$ kubectl get cs
NAME                 STATUS    MESSAGE             ERROR
scheduler            Healthy   ok                  
controller-manager   Healthy   ok                  
etcd-2               Healthy   {"health":"true"}   
etcd-0               Healthy   {"health":"true"}   
etcd-1               Healthy   {"health":"true"}   

可以,没问题,另一个节点不用试了,肯定也行,如果你的配置文件没有传到~/.kube目录下,你需要使用--kubeconfig=指定文件位置,这个文件妥善保管,这是管理员权限哦~

YAML配置文件资源管理

K8S也可以用YAML文件来创建资源对象,swarm也支持使用YAML文件来创建服务,像我之前写的swarm实战90%的服务都是用的YAML文件,K8S也支持使用json文件创建资源对象,推荐使用YAMLYAML语言比较方便,像ansibleplaybook也是用的YAML,语法格式之前写过了,这里就不多提了,下面实践一下。

使用YAML文件部署应用

[root@loadbalancer-1 ~/demo]$ cat nginx-deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

这个文件内容是直接在k8s官网上扒下来的示例,这个文件就是创建了一个Deployment,详解

apiVersion: apps/v1

指定当前部署Deployment资源版本,在k8S中所有的资源对象都时通过api分组去实现的,这里指定的api版本,API版本很多的,可以通过如下命令查看。

[root@loadbalancer-1 ~/demo]$ kubectl api-versions

v1表示这个资源组的稳定版本,beta为测试版,写YAML最好指定一个稳定版本。

kind: Deployment

指定资源的名字,你要是用哪个资源,现在使用的是Deployment

metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx

指定控制器的一些属性,Deployment是一个控制器,是源数据信息,像是指定了Deployment的名字、标签、副本数,通过标签管理具体的pods

  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

被管理对象,就是pod了,定义了容器Pod标签,标记哪个控制器来控制他,标签为nginx,也定义了容器名称为nginx,镜像为nginx:1.7.9,容器内部端口为80,控制器通过标签来匹配pod,通过这个文件描述出要创建一个怎样的资源对象,下面创建吧。

部署服务

现在可以使用这个文件去创建服务了,命令如下。

[root@loadbalancer-1 ~/demo]$ kubectl get pods -w
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-5c689d88bb-h6kx5   1/1     Running   0          4s
nginx-deployment-5c689d88bb-kdxhp   1/1     Running   0          4s
nginx-deployment-5c689d88bb-q54t8   1/1     Running   0          4s

已经创建好了,现在外部还无法访问,还需要创建一个service

发布服务

创建一个service,这个说白了就是一个负载均衡器,他帮你把请求转发到pods,下面创建一下。

[root@loadbalancer-1 ~/demo]$ cat nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  labels: 
    app: nginx
spec: 
  type: NodePort
  ports: 
  - port: 80
    targenPort: 80
  selector: 
    app: nginx

这里配置的是pod的标签,也就是nginx,请确保有所标签都是能匹配的到的,下面创建一下。

[root@loadbalancer-1 ~/demo]$ kubectl create -f nginx-service.yaml 
service/nginx-service created
[root@loadbalancer-1 ~/demo]$ kubectl get svc
NAME            TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
nginx-service   NodePort    10.0.0.218   <none>        80:30913/TCP   26s

现在循环访问节点的30913端口,响应头nginx版本为1.7.9就对了。

[root@master-1 ~]# for i in `echo 192.168.1.{202..204}:30913`; do   curl -I $i; done

没问题,像是更新回滚之类的一般不会写配置文件,直接用kubectl命令去做了,其实Deploymentservice的可以写到一个文件中,只需要使用---分隔就好了,这里大概了解一下就好。

生成YAML文件

其实YAML文件是可以生成的,使用kubectl就可以,现在把上面部署nginxYAML文件转成命令,大概是这样,这是Deployment的。

通过kubectl run

[root@loadbalancer-1 ~]$ kubectl run nginx --image=nginx:1.7.9 --replicas=3 --port=80 --dry-run 
kubectl run --generator=deployment/apps.v1beta1 is DEPRECATED and will be removed in a future version. Use kubectl create instead.
deployment.apps/nginx created (dry run)

加了--try-run只是测试命令是否能正常运行,而不会创建服务,具体这条命令会生成怎样的YAML文件,这样看。

[root@loadbalancer-1 ~]$ kubectl run nginx --image=nginx:1.7.9 --replicas=3 --port=80 --dry-run -o yaml
kubectl run --generator=deployment/apps.v1beta1 is DEPRECATED and will be removed in a future version. Use kubectl create instead.
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    run: nginx
  name: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      run: nginx
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        run: nginx
    spec:
      containers:
      - image: nginx:1.7.9
        name: nginx
        ports:
        - containerPort: 80
        resources: {}
status: {}

如要保存请重定向到一个文件就好,输出内容有点多,包括一些不透明的字段的都输出了,不单是你定义的那些,还有默认的值都被输出了,带有{}的都阔以删掉,其实和上面的差不多,现有资源的也能导出,具体如下。

使用kubectl get

现在有一个nginx的服务,现在把他Deploymentyaml导出来。

[root@loadbalancer-1 ~]$ kubectl get deployments.apps nginx-deployment -o yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
  creationTimestamp: 2019-03-05T06:09:17Z
  generation: 1
  labels:
    app: nginx
  name: nginx-deployment
  namespace: default
  resourceVersion: "624837"
  selfLink: /apis/apps/v1/namespaces/default/deployments/nginx-deployment
  uid: 35557b63-3f0d-11e9-a36e-000c297b5d6f
spec:
  progressDeadlineSeconds: 600
  replicas: 3
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: nginx
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.7.9
        imagePullPolicy: IfNotPresent
        name: nginx
        ports:
        - containerPort: 80
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  availableReplicas: 3
  conditions:
  - lastTransitionTime: 2019-03-05T06:09:20Z
    lastUpdateTime: 2019-03-05T06:09:20Z
    message: Deployment has minimum availability.
    reason: MinimumReplicasAvailable
    status: "True"
    type: Available
  - lastTransitionTime: 2019-03-05T06:09:17Z
    lastUpdateTime: 2019-03-05T06:09:20Z
    message: ReplicaSet "nginx-deployment-5c689d88bb" has successfully progressed.
    reason: NewReplicaSetAvailable
    status: "True"
    type: Progressing
  observedGeneration: 1
  readyReplicas: 3
  replicas: 3
  updatedReplicas: 3

导出service的如下。

[root@loadbalancer-1 ~]$ kubectl get service nginx-service -o yaml
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: 2019-03-05T05:54:28Z
  labels:
    app: nginx
  name: nginx-service
  namespace: default
  resourceVersion: "625746"
  selfLink: /api/v1/namespaces/default/services/nginx-service
  uid: 23786073-3f0b-11e9-93cc-000c2927dc19
spec:
  clusterIP: 10.0.0.218
  externalTrafficPolicy: Cluster
  ports:
  - nodePort: 30913
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
  sessionAffinity: None
  type: NodePort
status:
  loadBalancer: {}

也是要保存文件请重定向,就可以当模板了,这个用的偏多,把没用的删掉,我感觉命令我在get什么东西应该都能看懂,我就不多说了,大概就是这样。下面要深入了解一些东西了,上面的东西暂时都是了解一下,有个基本的概念。

最后编辑于: 2019 年 04 月 09 日
返回文章列表 文章二维码 打赏
本页链接的二维码
打赏二维码