使用 Amazon Ec2 + aws-k8s-cni 构建 K8s集群
在AWS上构建Kubernetes(K8S)时,通常使用EKS。
EKS 价格昂贵(每月约 10,000 日元),因此用于验证目的。
在 Amazon Linx2 上构建 K8S。
前提
・您必须拥有 AWS 账户。
注意
由于使用此过程卸载“ec2-net-utils”的影响 
重启实例时将不再分配公网IP。 
此过程是在公共子网中构建的,用于验证目的,但是
实际上,请将其构建在私有子网中。 
准备工作 各资源名称
K8S集群名称:dev-k8s-cluster
K8S 主 EC2:dev-k8s-master
K8S 节点 EC2:dev-k8s-node
创建 EC2 所需的资源
使用 AWS 控制台来完成您的工作。
①创建IAM角色 
② 选择可信实体。 
实体类型:AWS 服务
使用案例:EC2
③ 选择要使用的角色。 
使用的角色:AmazonEC2ContainerRegistryReadOnly
④创建角色。 
角色名称:dev-k8s-role
⑤创建安全组
⑥创建安全组。 
安全组名称:dev-k8s-security
描述:k8s EC2安全组
专有网络:默认专有网络
*此处无需设置任何带内规则。
创建完成后记下安全组ID。
⑦编辑带内规则。 
SSH:我的IP
所有流量: ⑥中记录的安全组ID
创建K8S主EC2
使用 AWS 控制台来完成您的工作。
① 从 EC2 菜单启动实例。 
②设置标签。 
键:名称,值:dev-k8s-master
Key: kubernetes.io/cluster/dev-k8s-cluster *请替换为您自己的集群名称。 ,价值:拥有
键:k8s-control-plane,值:*可以省略。
③ 为 AMI 设置 Amazon Linux。
④设置实例类型。 
实例类型:t3.small
*如果是t3.small,只要启动K8S就会耗尽内存。
如果您需要更多空间,请增加实例类型。
⑤创建密钥对。 
密钥对名称:dev-k8s-key
⑥ 设置网络。 
选择您在准备过程中创建的现有安全组。
安全组名称:dev-k8s-security
⑦设置存储。 
根体积:20G
⑧设置高级详细信息。 
在 IAM 实例配置文件中设置准备时创建的角色。
角色名称:dev-k8s-role
⑨启动EC2。
在主EC2上安装K8S
使用teraterm等工具通过SSH登录K8S主EC2并执行工作。
① 确认K8S master EC2的公网IP 
从 AWS 控制台的 EC2 列表中检查“dev-k8s-master”的详细信息。
②使用teraterm登录K8S master EC2。 
IP:①中确认的公网IP
用户名:ec2-user
密钥文件:上面创建的“dev-k8s-key”
③将EC2更新到最新状态。
| sudo yum update –y | 
④卸载ec2-net-utils。 
如果安装下面描述的 aws-k8s-cni 插件时包含 ec2-net-utils,
卸载它,因为行为变得不稳定。
| 1sudo yum remove ec2–net–utils –y | 
⑤ 安装容器运行时。 
运行时使用containerd。
| sudo amazon–linux–extras enable docker sudo yum install containerd –y | 
配置containerd自动启动。
| sudo systemctl enable —now containerd | 
检查状态。
⑥设置操作系统参数。
| cat >>EOF | sudo tee /etc/modules–load.d/containerd.conf overlay br_netfilter EOF sudo modprobe overlay sudo modprobe br_netfilter cat <<EOF | sudo tee /etc/sysctl.d/99–containerd.conf net.bridge.bridge–nf–call–iptables = 1 net.ipv4.ip_forward = 1 net.bridge.bridge–nf–call–ip6tables = 1 EOF sudo sysctl —system | 
⑦设置containerd的config.toml。
创建默认设置。
| sudo mkdir –p /etc/containerd sudo containerd config default | sudo tee /etc/containerd/config.toml | 
更改 config.toml 中的参数。
| 1sudo vi /etc/containerd/config.toml | 
变更详情
| [plugins.“io.containerd.grpc.v1.cri”.containerd.runtimes.runc]  ...  [plugins.“io.containerd.grpc.v1.cri”.containerd.runtimes.runc.options]   SystemdCgroup = true # ★ここの値を変更します。 | 
反映设置。
| 1sudo systemctl restart containerd | 
⑧添加tc模块,因为安装kubeadm时会出现警告。
| sudo ym install –y tc | 
⑨安装kubeadm、kubelet、kubectl。 
添加 K8S 存储库。
| sudo vi /etc/yum.repos.d/kubernetes.repo | 
文件内容: /etc/yum.repos.d/kubernetes.repo
| [kubernetes] name=Kubernetes baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch enabled=1 gpgcheck=1 repo_gpgcheck=0 gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg exclude=kubelet kubeadm kubectl | 
安装。
*这次我们将安装1.23版本。
| 1sudo yum install kubelet–1.23.7–0 kubectl–1.23.7–0 kubeadm–1.23.7–0 —disableexcludes=kubernetes –y | 
配置 kubelet 自动启动。
| 1sudo systemctl enable —now kubelet | 
检查状态。
这里K8S的建设还没有完成,所以处于停止状态。
| sudo systemctl status kubelet | 
⑩ 使用kubeadm安装K8S。
创建K8S的配置文件。
| vi config.yaml | 
文件内容:config.yaml
| apiVersion: kubeadm.k8s.io/v1beta3 kind: InitConfiguration nodeRegistration:  criSocket: “/run/containerd/containerd.sock” —– apiVersion: kubeadm.k8s.io/v1beta3 kind: ClusterConfiguration clusterName: “dev-k8s-cluster” # ★各自クラスタ名に置き換えてください。 controlPlaneEndpoint: ip–172–31–21–87.ap–northeast–1.compute.internal:6443 # ★hostnameコマンド等で取得したホスト名に置き換えてください。 | 
使用 kubeadm 命令安装 K8S。
| sudo kubeadm init —config config.yaml | 
请注意安装完成后出现的命令。 *上图红框部分
| kubeadm join ip–172–31–21–87.ap–northeast–1.compute.internal:6443 —token 6q1g4f.4m1dibndp5h0o5sn \ —discovery–token–ca–cert–hash sha256:cd753371f8fbd3802377ba35809648647a5e6295e09f2de6fb3e00f387fbeddc | 
添加K8S节点时会用到这个,所以一定要记下来。
⑪设置kubectl命令。
配置将 kubectl 命令与 ec2-user 结合使用的设置。
| mkdir –p $HOME/.kube sudo cp –i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id –u):$(id –g) $HOME/.kube/config | 
使用 kubectl 命令检查 pot 的状态。
| kubectl get po –A | 
*Coredns 正在等待处理,但这不是问题,因为网络插件尚未安装。
安装K8S网络插件
① 在AWS控制台中为EC2角色添加权限。 
角色名称:dev-k8s-role
②在内联策略中输入json。 
下面列出了所需的 iam。
 amazon-vpc-cni-k8s/iam-policy.md at master · aws/amazon-vpc-cni-k8s
amazon-vpc-cni-k8s/iam-policy.md at master · aws/amazon-vpc-cni-k8s 
| {  “Version”: “2012-10-17″,  “Statement”: [    {       “Effect”: “Allow”,       “Action”: [           “ec2:AssignPrivateIpAddresses”,           “ec2:AttachNetworkInterface”,           “ec2:CreateNetworkInterface”,           “ec2:DeleteNetworkInterface”,           “ec2:DescribeInstances”,           “ec2:DescribeTags”,           “ec2:DescribeNetworkInterfaces”,           “ec2:DescribeInstanceTypes”,           “ec2:DetachNetworkInterface”,           “ec2:ModifyNetworkInterfaceAttribute”,           “ec2:UnassignPrivateIpAddresses”,           “ec2:ModifyInstanceAttribute”       ],       “Resource”: “*”    },    {       “Effect”: “Allow”,       “Action”: [          “ec2:CreateTags”    ],    “Resource”: [          “arn:aws:ec2:*:*:network-interface/*”    ]   }  ] } | 
③创建内嵌策略。 
内联策略名称:dev-amazon-vpc-cni-k8s
④ 从 git 获取 amazon-vpc-cni-k8s yaml 文件。 
安装 git 命令。
| sudo yum install git –y | 
这次我们得到的版本是1.11.3
| git clone https://github.com/aws/amazon-vpc-cni-k8s.git -b v1.11.3 | 
编辑配置文件。
| cp amazon–vpc–cni–k8s/config/master/aws–k8s–cni.yaml amazon–vpc–cni–k8s/config/master/aws–k8s–cni.yaml.org vi amazon–vpc–cni–k8s/config/master/aws–k8s–cni.yaml | 
更改图像源和运行时间。
| —– # Source: aws-vpc-cni/templates/serviceaccount.yaml apiVersion: v1 kind: ServiceAccount metadata:   name: aws–node   namespace: kube–system   labels:     app.kubernetes.io/name: aws–node     app.kubernetes.io/instance: aws–vpc–cni     k8s–app: aws–node     app.kubernetes.io/version: “v1.11.3″ —– # Source: aws-vpc-cni/templates/customresourcedefinition.yaml apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata:   name: eniconfigs.crd.k8s.amazonaws.com   labels:     app.kubernetes.io/name: aws–node     app.kubernetes.io/instance: aws–vpc–cni     k8s–app: aws–node     app.kubernetes.io/version: “v1.11.3″ spec:   scope: Cluster   group: crd.k8s.amazonaws.com   preserveUnknownFields: false   versions:     – name: v1alpha1       served: true       storage: true       schema:         openAPIV3Schema:           type: object           x–kubernetes–preserve–unknown–fields: true   names:    plural: eniconfigs    singular: eniconfig    kind: ENIConfig —– # Source: aws-vpc-cni/templates/clusterrole.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata:   name: aws–node   labels:     app.kubernetes.io/name: aws–node     app.kubernetes.io/instance: aws–vpc–cni     k8s–app: aws–node     app.kubernetes.io/version: “v1.11.3″ rules:   – apiGroups:       – crd.k8s.amazonaws.com   resources:       – eniconfigs   verbs: [“list”, “watch”, “get”] – apiGroups: [“”]   resources:       – namespaces   verbs: [“list”, “watch”, “get”] – apiGroups: [“”]   resources:       – pods   verbs: [“list”, “watch”, “get”] – apiGroups: [“”]   resources:       – nodes   verbs: [“list”, “watch”, “get”, “update”] – apiGroups: [“extensions”]   resources:       – ‘*’   verbs: [“list”, “watch”] – apiGroups: [“”, “events.k8s.io”]   resources:       – events   verbs: [“create”, “patch”, “list”, “get”] —– # Source: aws-vpc-cni/templates/clusterrolebinding.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata:   name: aws–node   labels:     app.kubernetes.io/name: aws–node     app.kubernetes.io/instance: aws–vpc–cni     k8s–app: aws–node     app.kubernetes.io/version: “v1.11.3″ roleRef:   apiGroup: rbac.authorization.k8s.io   kind: ClusterRole   name: aws–node subjects:   – kind: ServiceAccount     name: aws–node     namespace: kube–system —– # Source: aws-vpc-cni/templates/daemonset.yaml kind: DaemonSet apiVersion: apps/v1 metadata:   name: aws–node   namespace: kube–system   labels:     app.kubernetes.io/name: aws–node     app.kubernetes.io/instance: aws–vpc–cni     k8s–app: aws–node     app.kubernetes.io/version: “v1.11.3″ spec:   updateStrategy:     rollingUpdate:       maxUnavailable: 10%     type: RollingUpdate   selector:     matchLabels:       k8s–app: aws–node   template:     metadata:       labels:         app.kubernetes.io/name: aws–node         app.kubernetes.io/instance: aws–vpc–cni         k8s–app: aws–node     spec:       priorityClassName: “system-node-critical”       serviceAccountName: aws–node       hostNetwork: true       initContainers:       – name: aws–vpc–cni–init         image: “602401143452.dkr.ecr.ap-northeast-1.amazonaws.com/amazon-k8s-cni-init:v1.11.3″ # ★ap-northeast-1に変更         env:           – name: DISABLE_TCP_EARLY_DEMUX             value: “false”           – name: ENABLE_IPv6             value: “false”         securityContext:             privileged: true         volumeMounts:           – mountPath: /host/opt/cni/bin             name: cni–bin–dir     terminationGracePeriodSeconds: 10     tolerations:       – operator: Exists     securityContext:       {}     containers:       – name: aws–node         image: “602401143452.dkr.ecr.ap-northeast-1.amazonaws.com/amazon-k8s-cni:v1.11.3″ # ★ap-northeast-1に変更         ports:           – containerPort: 61678             name: metrics         livenessProbe:           exec:             command:             – /app/grpc–health–probe             – –addr=:50051             – –connect–timeout=5s             – –rpc–timeout=5s           initialDelaySeconds: 60           timeoutSeconds: 10         readinessProbe:           exec:             command:             – /app/grpc–health–probe             – –addr=:50051             – –connect–timeout=5s             – –rpc–timeout=5s           initialDelaySeconds: 1           timeoutSeconds: 10         env:           – name: ADDITIONAL_ENI_TAGS             value: “{}”           – name: AWS_VPC_CNI_NODE_PORT_SUPPORT             value: “true”           – name: AWS_VPC_ENI_MTU             value: “9001”           – name: AWS_VPC_K8S_CNI_CONFIGURE_RPFILTER             value: “false”           – name: AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG             value: “false”           – name: AWS_VPC_K8S_CNI_EXTERNALSNAT             value: “false”           – name: AWS_VPC_K8S_CNI_LOGLEVEL             value: “DEBUG”           – name: AWS_VPC_K8S_CNI_LOG_FILE             value: “/host/var/log/aws-routed-eni/ipamd.log”           – name: AWS_VPC_K8S_CNI_RANDOMIZESNAT             value: “prng”           – name: AWS_VPC_K8S_CNI_VETHPREFIX             value: “eni”           – name: AWS_VPC_K8S_PLUGIN_LOG_FILE             value: “/var/log/aws-routed-eni/plugin.log”           – name: AWS_VPC_K8S_PLUGIN_LOG_LEVEL             value: “DEBUG”           – name: DISABLE_INTROSPECTION             value: “false”           – name: DISABLE_METRICS             value: “false”           – name: DISABLE_NETWORK_RESOURCE_PROVISIONING             value: “false”           – name: ENABLE_IPv4             value: “true”           – name: ENABLE_IPv6             value: “false”           – name: ENABLE_POD_ENI             value: “false”           – name: ENABLE_PREFIX_DELEGATION             value: “false”           – name: WARM_ENI_TARGET             value: “1”           – name: WARM_PREFIX_TARGET             value: “1”           – name: MY_NODE_NAME             valueFrom:               fieldRef:                 fieldPath: spec.nodeName         resources:           requests:             cpu: 25m         securityContext:           capabilities:             add:             – NET_ADMIN         volumeMounts:         – mountPath: /host/opt/cni/bin           name: cni–bin–dir         – mountPath: /host/etc/cni/net.d           name: cni–net–dir         – mountPath: /host/var/log/aws–routed–eni           name: log–dir         – mountPath: /var/run/cri.sock # ★ cri.sockに変更           name: containerd # ★ containerdに変更         – mountPath: /var/run/aws–node           name: run–dir         – mountPath: /run/xtables.lock           name: xtables–lock     volumes:     – name: cni–bin–dir       hostPath:         path: /opt/cni/bin     – name: cni–net–dir       hostPath:         path: /etc/cni/net.d     – name: containerd # ★ containerdに変更       hostPath:         path: /run/containerd/containerd.sock # ★ containerd.sockに変更     – name: log–dir       hostPath:         path: /var/log/aws–routed–eni         type: DirectoryOrCreate     – name: run–dir       hostPath:         path: /var/run/aws–node         type: DirectoryOrCreate     – name: xtables–lock       hostPath:         path: /run/xtables.lock     affinity:       nodeAffinity:         requiredDuringSchedulingIgnoredDuringExecution:           nodeSelectorTerms:           – matchExpressions:             – key: kubernetes.io/os               operator: In               values:               – linux             – key: kubernetes.io/arch               operator: In               values:               – amd64               – arm64             – key: eks.amazonaws.com/compute–type               operator: NotIn               values:               – fargate | 
⑤在K8S上安装。
| kubectl apply –f amazon–vpc–cni–k8s/config/master/aws–k8s–cni.yaml | 
使用 kubectl 命令检查 pod 的状态。
| kubectl get po –A | 
*当 coredns 变为 Running 时,安装完成。
创建K8S节点EC2。
使用 AWS 控制台来完成您的工作。
① 从 EC2 菜单启动实例。
②设置标签。 
键:名称,值:dev-k8s-node
Key: kubernetes.io/cluster/dev-k8s-cluster *请替换为您自己的集群名称。 ,价值:拥有
③ 为 AMI 设置 Amazon Linux。
④设置实例类型和密钥对。 
实例类型:t3.small
密钥对名称:dev-k8s-key
⑥ 设置网络。 
选择您在准备过程中创建的现有安全组。
安全组名称:dev-k8s-security
⑦设置存储和角色。 
根卷:8G *保留默认值。
角色名称:dev-k8s-role
⑧创建EC2。
在节点 EC2 上安装 K8S
使用teraterm等工具登录K8S master EC2并执行工作。
①K8S master EC2全局IP确认 
从 AWS 控制台的 EC2 列表中检查“dev-k8s-node”的详细信息。
②使用teraterm登录K8S master EC2。 
IP:①中确认的全球IP
用户名:ec2-user
密钥文件:上面创建的“dev-k8s-key”
③EC2を最新の状態にアップデートします。
| sudo yum update –y | 
④卸载ec2-net-utils。 
如果安装下面描述的 aws-k8s-cni 插件时包含 ec2-net-utils,
卸载它,因为行为变得不稳定。
| sudo yum remove ec2–net–utils –y | 
⑤ 安装容器运行时。 
运行时使用containerd。
| sudo amazon–linux–extras enable docker sudo yum install containerd –y | 
配置containerd自动启动。
| sudo sysemctl enable —now containerd | 
检查状态。
| sudo systemctl status containerd | 
⑥设置操作系统参数。
| cat <<EOF | sudo tee /etc/modules–load.d/containerd.conf overlay br_netfilter EOF sudo modprobe overlay sudo modprobe br_netfilter cat <<EOF | sudo tee /etc/sysctl.d/99–containerd.conf net.bridge.bridge–nf–call–iptables = 1 net.ipv4.ip_forward = 1 net.bridge.bridge–nf–call–ip6tables = 1 EOF sudo sysctl —system | 
⑦设置containerd的config.toml。
创建默认设置。
| sudo mkdir –p /etc/containerd sudo containerd config default | sudo tee /etc/containerd/config.toml | 
更改 config.toml 中的参数。 
| sudo vi /etc/containerd/config.toml | 
文件内容:config.yaml
| [plugins.“io.containerd.grpc.v1.cri”.containerd.runtimes.runc]   ...   [plugins.“io.containerd.grpc.v1.cri”.containerd.runtimes.runc.options]     SystemdCgroup = true # ★ここの値を変更します。 | 
反映设置。
| sudo systemctl restart containerd | 
⑧添加tc模块,因为安装kubeadm时会出现警告。
| sudo yum install –y tc | 
⑨安装kubeadm、kubelet、kubectl。
添加 K8S 存储库。
| sudo vi /etc/yum.repos.d/kubernetes.repo | 
文件内容:/etc/yum.repos.d/kubernetes.repo
| [kubernetes] name=Kubernetes baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch enabled=1 gpgcheck=1 repo_gpgcheck=0 gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg exclude=kubelet kubeadm kubectl | 
安装。
*这次我们将安装1.23版本。 
| sudo yum install kubelet–1.23.7–0 kubectl–1.23.7–0 kubeadm–1.23.7–0 —disableexcludes=kubernetes –y | 
配置 kubelet 自动启动。
| sudo systemctl enable —now kubelet | 
检查状态。
这里K8S的建设还没有完成,所以处于停止状态。
| sudo systemctl status kubelet | 
⑩ 使用kubeadm链接K8S主EC2。
使用在主 EC2 上安装 K8S 时显示的命令。
使用 sudo 运行它并添加选项“–cri-socket=/run/containerd/containerd.sock”。
| sudo kubeadm join ip–172–31–21–87.ap–northeast–1.compute.internal:6443 —token 6q1g4f.4m1dibndp5h0o5sn \         —discovery–token–ca–cert–hash sha256:cd753371f8fbd3802377ba35809648647a5e6295e09f2de6fb3e00f387fbeddc \         —cri–socket=/run/containerd/containerd.sock | 
检查K8S主EC2上的状态。
通过SSH登录K8S主EC2,使用kubectl命令查看节点状态。
| kubectl get node | 
如果 STATUS 为“Ready”,则表示正常。
部署示例 nginx。
①创建nginx yaml文件。
文件内容:nginx.yaml
| apiVersion: apps/v1 kind: Deployment metadata:   name: nginx spec:   selector:     matchLabels:       app: nginx   replicas: 1   template:     metadata:       labels:         app: nginx   spec:     containers:     – name: nginx       image: nginx:1.23.2       ports:       – containerPort: 80 —– apiVersion: v1 kind: Service metadata:   labels:           app: nginx   name: nginx spec:   type: NodePort   selector:     app: nginx   ports:     – port: 80 | 
②部署nginx。
| kubectl apply –f nginx.yaml | 
③ 检查nginx的部署情况。
| kubectl get po | 
如果 STATUS 为“Runnin”,则表示正常。
④ 检查服务的节点端口。
| kubectl get svc | 
检查 PORT 中是否显示“80:30366”。
节点端口将为“30366”。
⑤ 更改安全组,使其可以从外部访问。 
登录 AWS 控制台并完成您的工作。
目标安全组:dev-k8s-security
将以下内容添加到您的带内规则中:
类型:自定义 TCP
端口范围:30366 *这是上面确认的节点端口。
来源:我的 IP *这用作我的 IP 以进行验证。 如果您想公开,可以输入“0.0.0.0/0”等。
⑥ 使用浏览器访问nginx。 
URL:http://K8S节点EC2公网IP:30366 *这是上面确认的节点端口。
如果显示nginx页面则正常。

 QQ咨询
QQ咨询 
		




































