kubeadm

架构

  • kubelet要操作宿主机上的网络、存储、文件系统,所以直接部署在宿主机上
  • 使用容器部署其他组件

    部署

    ```shell

    安装kubeadm

    $ apt-get install kubeadm

创建一个Master节点

$ kubeadm init —config kubeadm.yaml # yaml文件定制部署参数

将一个Node节点加入到当前集群中

$ kubeadm join

  1. ```yaml
  2. # yaml文件定制部署参数
  3. # 这些参数会替换 /etc/kubernetes/manifests/下对应的文件里的参数
  4. apiVersion: kubeadm.k8s.io/v1alpha2
  5. kind: MasterConfiguration
  6. kubernetesVersion: v1.11.0
  7. api:
  8. advertiseAddress: 192.168.0.102
  9. bindPort: 6443
  10. ...
  11. etcd:
  12. local:
  13. dataDir: /var/lib/etcd
  14. image: ""
  15. imageRepository: k8s.gcr.io
  16. kubeProxy:
  17. config:
  18. bindAddress: 0.0.0.0
  19. ...
  20. kubeletConfiguration:
  21. baseConfig:
  22. address: 0.0.0.0
  23. ...
  24. networking:
  25. dnsDomain: cluster.local
  26. podSubnet: ""
  27. serviceSubnet: 10.96.0.0/12
  28. nodeRegistration:
  29. criSocket: /var/run/dockershim.sock
  30. ...

工作流程

  • init
    • preflight checks
      • 内核版本要大于3.10
      • cgroups模式是否可用
      • hostname是否标准
      • kubeadm、kubelet版本是否匹配
      • k8s的工作端口10250/10251/10252是否被占用
      • ip、mount等linux指令是否存在
      • docker是否安装
    • 生成对外提供服务所需的各种证书和对应的目录
      • 除非开启“不安全模式”,否则都必须通过https访问kube-apiserver,需要配置证书文件
      • /etc/kubernetes/pki目录下主要包含ca.crt和ca.key、kubelet-client.crt和apiserver-kubelet-client.key等证书
    • 生成其他组件访问kube-apiserver所需要的配置文件(master节点的地址/端口/证书目录等信息)
      • /etc/kubernetes/admin.conf
      • /etc/kubernetes/scheduler.conf
      • /etc/kubernetes/controller-manager.conf
      • /etc/kubernetes/kubelet.conf
    • 为master节点生成pod配置文件,通过StaticPod部署(要部署的pod的YAML文件放在指定目录/etc/kubernetes/manifests/,kubelet启动时会自动检测并加载启动,启动StaticPod后,kubeadm通过检查 localhost:6443/healthz做master的健康检查,等待master组件全部运行起来)
      • kube-apiserver.yaml
      • kube-controller-manager.yaml
      • kube-scheduler.yaml
      • etcd.yaml
    • kubeadm为集群生成一个bootstrap token并存储cluster-info
      • 只要持有这个token,任何一个安装了kubelet和kubeadm的节点都可以join进集群
      • token生成后kubeadm会将ca.crt等master节点的重要信息,通过cm保存在etcd,供后续部署node节点使用,这个cm的名字是cluster-info
    • 安装默认插件
      • kube-proxy和DNS这两个插件是必须安装的
      • 也是以pod方式部署
  • join

    • 加入集群需要在kube-apiserver上注册
    • 要和kube-apiserver交互必须获取相应的证书
    • 为了能够一键安装,不能让用户去master节点上手动拷贝
    • 所以kubeadm至少发起一次“不安全模式”的访问,拿到cm中的cluster-info
    • 这次“不安全模式”的访问就是通过token进行安全验证的
    • 拿到cluster-info后就可以以安全模式连接到apiserver上

      完整K8s集群

      准备工作

  • 64位linuxOS,3.10及以上的内核版本

  • 外网访问权限
  • 30GB磁盘留给docker镜像和日志

    部署步骤

  1. 安装docker和kubeadm ```shell

$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - $ cat < /etc/apt/sources.list.d/kubernetes.list

deb http://apt.kubernetes.io/ kubernetes-xenial main

deb http://mirrors.ustc.edu.cn/kubernetes/apt kubernetes-xenial main #中科大镜像 EOF $ apt-get update $ apt-get install -y docker.io kubeadm


2. 部署master
```yaml
# kubeadm.yaml
apiVersion: kubeadm.k8s.io/v1alpha1
kind: MasterConfiguration
controllerManagerExtraArgs:
  horizontal-pod-autoscaler-use-rest-clients: "true"
  horizontal-pod-autoscaler-sync-period: "10s"
  node-monitor-grace-period: "10s"
apiServerExtraArgs:
  runtime-config: "api/all=true"
kubernetesVersion: "stable-1.11"

$ kubeadm init --config kubeadm.yaml

# kubectl默认使用以下授权信息访问集群
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

NAME      STATUS     ROLES     AGE       VERSION
master    NotReady   master    1d        v1.11.1

$ kubectl describe node master

...
Conditions:
...

Ready   False ... KubeletNotReady  runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized
  1. 部署容器网络插件 ```shell

$ kubectl apply -f https://git.io/weave-kube-1.6

$ kubectl get pods -n kube-system

NAME READY STATUS RESTARTS AGE coredns-78fcdf6894-j9s52 1/1 Running 0 1d coredns-78fcdf6894-jm4wf 1/1 Running 0 1d etcd-master 1/1 Running 0 9s kube-apiserver-master 1/1 Running 0 9s kube-controller-manager-master 1/1 Running 0 9s kube-proxy-xbd47 1/1 Running 0 1d kube-scheduler-master 1/1 Running 0 9s weave-net-cmk27 2/2 Running 0 19s


4. 部署worker
```shell

$ kubeadm join 10.168.0.2:6443 --token 00bwbx.uvnaa2ewjflwu1ry --discovery-token-ca-cert-hash sha256:00eb62a2a6020f94132e3fe1ab721349bbcd3e9b94da9654cfe15f2985ebd711
  • 通过Taint/Toleration调整master执行pod的策略 ```shell

    打taint

    $ kubectl taint nodes node1 foo=bar:NoSchedule

配置文件声明tolerations

apiVersion: v1 kind: Pod … spec: tolerations:

  • key: “foo” operator: “Equal” value: “bar” effect: “NoSchedule”

查看taints

$ kubectl describe node master

Name: master Roles: master Taints: node-role.kubernetes.io/master:NoSchedule

删除taints

$ kubectl taint nodes —all node-role.kubernetes.io/master-


5. 部署dashboard插件
```shell

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-rc6/aio/deploy/recommended.yaml

$ kubectl get pods -n kube-system

kubernetes-dashboard-6948bdb78-f67xk   1/1       Running   0          1m
  1. 部署存储插件 ```shell

    Rook是基于ceph的存储插件,生产级别可用的企业级插件

$ kubectl apply -f https://raw.githubusercontent.com/rook/rook/master/cluster/examples/kubernetes/ceph/common.yaml

$ kubectl apply -f https://raw.githubusercontent.com/rook/rook/master/cluster/examples/kubernetes/ceph/operator.yaml

$ kubectl apply -f https://raw.githubusercontent.com/rook/rook/master/cluster/examples/kubernetes/ceph/cluster.yaml

$ kubectl get pods -n rook-ceph-system NAME READY STATUS RESTARTS AGE rook-ceph-agent-7cv62 1/1 Running 0 15s rook-ceph-operator-78d498c68c-7fj72 1/1 Running 0 44s rook-discover-2ctcv 1/1 Running 0 15s

$ kubectl get pods -n rook-ceph NAME READY STATUS RESTARTS AGE rook-ceph-mon0-kxnzh 1/1 Running 0 13s rook-ceph-mon1-7dn2t 1/1 Running 0 2s

<a name="csF1U"></a>
# 第一个容器化应用
<a name="8OXBX"></a>
## yaml

- 使用一种api对象(deployment)管理另一种api对象(pod)的方法叫做控制器模式
- 对api对象的定义主要分为以下两部分
   - metadata
      - labels 
      - annotations 专门携带key-value内部信息(k8s本身关心,应用不关心,大多数都是k8s自动加上)
   - spec
<a name="ooT3e"></a>
## deployment
```yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.8
        ports:
        - containerPort: 80
        volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: nginx-vol
      volumes:
      - name: nginx-vol
        emptyDir: {} #使用隐式目录,即k8s自动创建的临时目录,也可以使用 hostPath模式
        # hostPath:
        #     path: "/var/data"