Use k8s on AWS - EKS service

k8s最近是风头很盛,因为它解决了容器集群的管理和调度问题,所以大家都想一试究竟——包括我,一般如果没有云账号的同学,只能自己下载k8s的软件装在本地服务器上,还要下载k8s相关的插件,配置网络等等一系列设置,经过各种调试才能正常运行。这种方式对于用过云的朋友自然是拒绝的——包括我,实用主义告诉我们,只要更快达到目的不论过程和手段,能直接用托管的,干嘛费力费时找条弯路走呢。

-- D.C

先上个珍藏多年的k8s基础原理图:

k8s

名词解释

kube-apiserver : k8s对外的服务入口,通信纽带,无状态,水平扩展。

Kube-scheduler : 负责对pod的任务调度。

kube-controller-manager : 处理node节点的当机啊,pod的副本数啊,管理endpoint终端节点,连接service和pod、为新的命名空间创建默认api token和accounts。

etcd : etcd是kubernetes集群用来存储集群相关数据的数据仓库。

kubelet :负责启动停止容器,保证容器运行。

kube-proxy :负责根据service生成网络规则,生成路由规则。

Docker engine : 这个不用说了,一个pod里面可以有一个或多个容器。

PID命名空间 : Pod中的不同应用程序可以看到其他应用程序的进程ID。

网络命名空间 : Pod中的多个容器能够访问同一个IP和端口范围。

IPC命名空间 : Pod中的多个容器能够使用SystemV IPC或POSIX消息队列进行通信。

UTS命名空间 : Pod中的多个容器共享一个主机名。

Volumes(共享存储卷) : Pod中的各个容器可以访问在Pod级别定义的Volumes。

好了,就说到这里,了解这么多我觉得就够了,再说会晕。

从头搭建k8s

这种搭建方式只有一种可能,就是本地传统玩家,教程网上一大堆,这里只介绍基本步骤:

好似裹脚布,又臭又长,感觉每一步都可能缠住我的脖子,让我分分钟从入门到放弃。

EKS - managed k8s on aws

aws 托管的k8s服务(目前更新到1.15),中国区可用,是一项完全托管的 Kubernetes 服务。出于其安全性、可靠性和可扩展性,Intel、Snap、Intuit、GoDaddy 和 Autodesk 等客户都在使用它来运行他们最敏感的任务关键型应用程序。

EKS有几个特性:

EKS部署有三种方式:

好了,了解到这里也够了,否则就不叫托管了。

一键创建EKS集群(k8s)

$ eksctl create cluster \
>     --name myeks \
>     --version 1.15 \
>     --region cn-northwest-1 \
>     --nodegroup-name workers \
>     --node-type m5.large \
>     --nodes 3 \
>     --managed
[ℹ]  eksctl version 0.15.0
[ℹ]  using region cn-northwest-1
[ℹ]  setting availability zones to [cn-northwest-1c cn-northwest-1a cn-northwest-1b]
[ℹ]  subnets for cn-northwest-1c - public:192.168.xx.xx/19 private:192.168.xx.xx/19
[ℹ]  subnets for cn-northwest-1a - public:192.168.xx.xx/19 private:192.168.xx.xx/19
[ℹ]  subnets for cn-northwest-1b - public:192.168.xx.xx/19 private:192.168.xx.xx/19
[ℹ]  using Kubernetes version 1.15
[ℹ]  creating EKS cluster "myeks" in "cn-northwest-1" region with managed nodes
[ℹ]  will create 2 separate CloudFormation stacks for cluster itself and the initial managed nodegroup
[ℹ]  if you encounter any issues, check CloudFormation console or try 'eksctl utils describe-stacks --region=cn-northwest-1 --cluster=myeks'
[ℹ]  CloudWatch logging will not be enabled for cluster "myeks" in "cn-northwest-1"
[ℹ]  you can enable it with 'eksctl utils update-cluster-logging --region=cn-northwest-1 --cluster=myeks'
[ℹ]  Kubernetes API endpoint access will use default of {publicAccess=true, privateAccess=false} for cluster "myeks" in "cn-northwest-1"
[ℹ]  2 sequential tasks: { create cluster control plane "myeks", create managed nodegroup "workers" }
[ℹ]  building cluster stack "eksctl-myeks-cluster"
[ℹ]  deploying stack "eksctl-myeks-cluster"
[ℹ]  building managed nodegroup stack "eksctl-myeks-nodegroup-workers"
[ℹ]  deploying stack "eksctl-myeks-nodegroup-workers"
[✔]  all EKS cluster resources for "myeks" have been created
[✔]  saved kubeconfig as "C:\\Users\\xxx/.kube/config"
[ℹ]  nodegroup "workers" has 3 node(s)
[ℹ]  node "ip-192-168-xx-xx.cn-northwest-1.compute.internal" is ready
[ℹ]  node "ip-192-168-xx-xx.cn-northwest-1.compute.internal" is ready
[ℹ]  node "ip-192-168-xx-xx.cn-northwest-1.compute.internal" is ready
[ℹ]  waiting for at least 3 node(s) to become ready in "workers"
[ℹ]  nodegroup "workers" has 3 node(s)
[ℹ]  node "ip-192-168-xx-xx.cn-northwest-1.compute.internal" is ready
[ℹ]  node "ip-192-168-xx-xx.cn-northwest-1.compute.internal" is ready
[ℹ]  node "ip-192-168-xx-xx.cn-northwest-1.compute.internal" is ready
[ℹ]  kubectl command should work with "C:\\Users\\xxx/.kube/config", try 'kubectl get nodes'
[✔]  EKS cluster "myeks" in "cn-northwest-1" region is ready

这样默认部署的集群架构长这样,当然后期我也可以看eks文档按照我实际工作调整:

eksdefault

myeks

myworker

PS: 其实呢,一键部署背后还是调用了AWS的自动化部署神器 - CloudFormation

CF

--vpc-public-subnets public_subnet_1a, public_subnet_1b \
--vpc-private-subnets private_subnet_1a, prviate_subnet_1b \
--ssh-public-key eks-bjs # 指定现有的pem文件

--node-ami ami-xxxx # 可以指定自己的ami, but --managed unable to used

--node-ami-family # 指定OS系统, default is Amazon Linux 2
# AmazonLinux2, Ubuntu1804, WindowsServer2019FullContainer, WindowsServer2019CoreContainer

$ AWS_PROFILE=bjs # 指定用哪个aksk身份来创建集群 cat ~/.aws/config 可以看

管理EKS

$ aws eks update-kubeconfig --name <cluster_name>

例如:

$ aws eks update-kubeconfig --name myeks
Added new context arn:aws-cn:eks:cn-northwest-1:xxxxxxxxxxxx:cluster/myeks to C:\Users\xxxx\.kube\config
$ kubectl get nodes
NAME                                                STATUS   ROLES    AGE     VERSION
ip-192-168-xx-xx.cn-northwest-1.compute.internal   Ready    <none>   7m55s   v1.15.10-eks-bac369
ip-192-168-xx-xx.cn-northwest-1.compute.internal    Ready    <none>   7m49s   v1.15.10-eks-bac369
ip-192-168-xx-xx.cn-northwest-1.compute.internal    Ready    <none>   7m41s   v1.15.10-eks-bac369

部署应用

$ vim dockerfile
FROM nginx 
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

myecr

$ docker build . -t xxxxxxxxxxx.dkr.ecr.cn-northwest-1.amazonaws.com.cn/ekstest

$ docker images
REPOSITORY                                                     TAG                 IMAGE ID            CREATED             SIZE
xxxxxxxxxxx.dkr.ecr.cn-northwest-1.amazonaws.com.cn/ekstest   latest              fef472de0787        47 hours ago        127MB
nginx                                                          latest              ed21b7a8aee9        2 weeks ago         127MB


$ aws ecr get-login-password --region cn-northwest-1 | docker login --username AWS --password-stdin xxxxxxxxxxx.dkr.ecr.cn-northwest-1.amazonaws.com.cn/ekstest
Login Succeeded

$ docker push xxxxxxxxxxx.dkr.ecr.cn-northwest-1.amazonaws.com.cn/ekstest:latest

可以看到这个docker已经推到仓库了。

myecr

创建YAML文件 nginx-deployment.yaml, 部署nginx

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: <account_id>.dkr.ecr.cn-northwest-1.amazonaws.com.cn/ekstest:latest # 自行修改ID
        ports:
        - containerPort: 80
$ kubectl.exe apply -f nginx-deployment.yaml
deployment.apps/nginx-deployment created

$ kubectl.exe get pods
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-75d669445d-k2nqg   1/1     Running   0          2m46s
nginx-deployment-75d669445d-x6z7d   1/1     Running   0          2m46s
nginx-deployment-75d669445d-xdfdx   1/1     Running   0          2m46s

创建YAML文件 nginx-svc-nlb.yaml,部署类型为负载均衡器的service (AWS Network Load Balance 服务)

apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
spec:
  type: LoadBalancer
  selector:
    app: nginx
  ports:
  - protocol: TCP
    name: http
    port: 80
    targetPort: 80
$ kubectl.exe apply -f nginx-svc-nlb.yaml
service/nginx-svc created

$ kubectl.exe get svc
NAME         TYPE           CLUSTER-IP       EXTERNAL-IP                                                                             PORT(S)        AGE
kubernetes   ClusterIP      10.100.0.1       <none>                                                                                  443/TCP        51m
nginx-svc    LoadBalancer   10.100.179.159   a9d4exxxxxxxxxxxxxxxxxxxxxx-dd11xxxxxxx.elb.cn-northwest-1.amazonaws.com.cn   80:30428/TCP   30s

可以看到负载均衡器已经起来了,我们在aws console中可以看到负载均衡器状态从 provisioning 变成 active

nlb

yes

关于k8s里的IP地址

Kubernetes集群里有三种IP地址,分别如下:

学习链接

人生苦短,我用托管。