| copyright |
|
||
|---|---|---|---|
| lastupdated | 2020-08-27 | ||
| keywords | kubernetes, iks | ||
| subcollection | containers | ||
| content-type | tutorial | ||
| services | containers, vpc | ||
| account-plan | |||
| completion-time | 30m |
{:DomainName: data-hd-keyref="APPDomain"} {:DomainName: data-hd-keyref="DomainName"} {:android: data-hd-operatingsystem="android"} {:apikey: data-credential-placeholder='apikey'} {:app_key: data-hd-keyref="app_key"} {:app_name: data-hd-keyref="app_name"} {:app_secret: data-hd-keyref="app_secret"} {:app_url: data-hd-keyref="app_url"} {:authenticated-content: .authenticated-content} {:beta: .beta} {:c#: data-hd-programlang="c#"} {:codeblock: .codeblock} {:curl: .ph data-hd-programlang='curl'} {:deprecated: .deprecated} {:dotnet-standard: .ph data-hd-programlang='dotnet-standard'} {:download: .download} {:external: target="_blank" .external} {:faq: data-hd-content-type='faq'} {:fuzzybunny: .ph data-hd-programlang='fuzzybunny'} {:generic: data-hd-operatingsystem="generic"} {:generic: data-hd-programlang="generic"} {:gif: data-image-type='gif'} {:go: .ph data-hd-programlang='go'} {:help: data-hd-content-type='help'} {:hide-dashboard: .hide-dashboard} {:hide-in-docs: .hide-in-docs} {:important: .important} {:ios: data-hd-operatingsystem="ios"} {:java: #java .ph data-hd-programlang='java'} {:java: .ph data-hd-programlang='java'} {:java: data-hd-programlang="java"} {:javascript: .ph data-hd-programlang='javascript'} {:javascript: data-hd-programlang="javascript"} {:new_window: target="_blank"} {:note: .note} {:objectc data-hd-programlang="objectc"} {:org_name: data-hd-keyref="org_name"} {:php: data-hd-programlang="php"} {:pre: .pre} {:preview: .preview} {:python: .ph data-hd-programlang='python'} {:python: data-hd-programlang="python"} {:route: data-hd-keyref="route"} {:row-headers: .row-headers} {:ruby: .ph data-hd-programlang='ruby'} {:ruby: data-hd-programlang="ruby"} {:runtime: architecture="runtime"} {:runtimeIcon: .runtimeIcon} {:runtimeIconList: .runtimeIconList} {:runtimeLink: .runtimeLink} {:runtimeTitle: .runtimeTitle} {:screen: .screen} {:script: data-hd-video='script'} {:service: architecture="service"} {:service_instance_name: data-hd-keyref="service_instance_name"} {:service_name: data-hd-keyref="service_name"} {:shortdesc: .shortdesc} {:space_name: data-hd-keyref="space_name"} {:step: data-tutorial-type='step'} {:subsection: outputclass="subsection"} {:support: data-reuse='support'} {:swift: #swift .ph data-hd-programlang='swift'} {:swift: .ph data-hd-programlang='swift'} {:swift: data-hd-programlang="swift"} {:table: .aria-labeledby="caption"} {:term: .term} {:tip: .tip} {:tooling-url: data-tooling-url-placeholder='tooling-url'} {:troubleshoot: data-hd-content-type='troubleshoot'} {:tsCauses: .tsCauses} {:tsResolve: .tsResolve} {:tsSymptoms: .tsSymptoms} {:tutorial: data-hd-content-type='tutorial'} {:unity: .ph data-hd-programlang='unity'} {:url: data-credential-placeholder='url'} {:user_ID: data-hd-keyref="user_ID"} {:vb.net: .ph data-hd-programlang='vb.net'} {:video: .video}
{: #vpc_ks_tutorial} {: toc-content-type="tutorial"} {: toc-services="containers, vpc"} {: toc-completion-time="30m"}
Create an {{site.data.keyword.containerlong}} cluster on Virtual Private Cloud (VPC) Generation 2 compute. {: shortdesc}
With {{site.data.keyword.containerlong_notm}} clusters on VPC Generation 2 compute, you can create your cluster on VPC infrastructure in the next generation of the {{site.data.keyword.cloud_notm}} platform, in your Virtual Private Cloud. VPC gives you the security of a private cloud environment with the dynamic scalability of a public cloud. VPC uses the next version of {{site.data.keyword.containerlong_notm}} infrastructure providers, with a select group of v2 API, CLI, and console functionality. You can create only standard clusters for VPC.
Want to create a cluster in your Virtual Private Cloud (VPC) on generation 1 compute instead? See Creating a standard VPC Gen 1 compute cluster.
{: tip}
{: #vpc_ks_objectives}
In the tutorial lessons, you create an {{site.data.keyword.containerlong_notm}} cluster in a Gen 2 Virtual Private Cloud (VPC). Then, you deploy an app and expose the app publicly by using a load balancer.
{: #vpc_ks_audience}
This tutorial is for administrators who are creating a cluster in {{site.data.keyword.containerlong_notm}} in VPC Generation 2 compute for the first time. {: shortdesc}
{: #vpc_ks_prereqs}
Ensure that you have the following {{site.data.keyword.cloud_notm}} IAM access policies.
- Administrator platform role for VPC Infrastructure.
- Administrator platform role for {{site.data.keyword.containerlong_notm}}.
- Writer or Manager service role for {{site.data.keyword.containerlong_notm}}.
- Administrator platform role for Container Registry.
If this cluster is not the first cluster in the region and resource group, make sure that the API key for the region and resource group that you plan to create the cluster in is set up with the correct infrastructure permissions.
Install the command-line tools. * [Install the {{site.data.keyword.cloud_notm}} CLI (`ibmcloud`), {{site.data.keyword.containershort_notm}}plug-in (`ibmcloud ks`), and {{site.data.keyword.registrylong_notm}} plug-in (`ibmcloud cr`)](/docs/containers?topic=containers-cs_cli_install#cs_cli_install_steps). * Update your {{site.data.keyword.containerlong_notm}} plug-in to the latest version. ``` ibmcloud plugin update kubernetes-service ``` {: pre} * To work with VPC, install the `infrastructure-service` plug-in. The prefix for running commands is `ibmcloud is`. ``` ibmcloud plugin install infrastructure-service ``` {: pre} * Make sure that the [`kubectl` version](/docs/containers?topic=containers-cs_cli_install#kubectl) matches the Kubernetes version of your VPC cluster. This tutorial creates a cluster that runs version **1.17.3**.
{: #vpc_ks_create_vpc_cluster} {: step}
Create an {{site.data.keyword.containerlong_notm}} cluster in your {{site.data.keyword.cloud_notm}} Virtual Private Cloud (VPC) environment. For more information about VPC, see Getting Started with Virtual Private Cloud. {: shortdesc}
-
Log in to the {{site.data.keyword.cloud_notm}} region where you want to create your VPC environment. The VPC must be set up in the same multizone metro location where you want to create your cluster. In this tutorial you create a VPC in
us-south. For other supported regions, see Multizone metros for VPC clusters. The VPC can be in a separate resource group than the resource group of your cluster. If you have a federated ID, include the--ssoflag.ibmcloud login -r us-south [--sso]{: pre}
-
Create a VPC for your cluster. For more information, see the docs for creating a VPC in the console or CLI.
-
Target the VPC infrastructure generation 2.
ibmcloud is target --gen 2{: pre}
-
Create a VPC that is called
myvpcand note the ID in the output. VPCs provide an isolated environment for your workloads to run within the public cloud. You can use the same VPC for multiple clusters, such as if you plan to have different clusters host separate microservices that need to communicate with each other. If you want to separate your clusters, such as for different departments, you can create a VPC for each cluster.ibmcloud is vpc-create myvpc{: pre}
-
Create a subnet for your VPC, and note its ID. Consider the following information when you create the VPC subnet:
- Zones: You must have one VPC subnet for each zone in your cluster. The available zones depend on the metro location that you created the VPC in. To list available zones in the region, run
ibmcloud is zones. - IP addresses: VPC subnets provide private IP addresses for your worker nodes and load balancer services in your cluster, so make sure to create a subnet with enough IP addresses, such as 256. You cannot change the number of IP addresses that a VPC subnet has later.
- Public gateways: You do not need to attach a public gateway to complete this tutorial. Instead, you can keep your worker nodes isolated from public access by using VPC load balancers to expose workloads securely. You might attach a public gateway if your worker nodes need to access a public URL. For more information, see Planning your cluster network setup.
- Network traffic control: Set up network access control lists (ACLs) to control inbound and outbound network traffic at the subnet level. Each subnet includes a default ACL that permits all inbound and outbound traffic.
ibmcloud is subnet-create mysubnet1 <vpc_ID> --zone us-south-1 --ipv4-address-count 256{: pre}
- Zones: You must have one VPC subnet for each zone in your cluster. The available zones depend on the metro location that you created the VPC in. To list available zones in the region, run
-
-
To allow any traffic requests to apps that you deploy on your worker nodes, modify the VPC's default security group.
- List your security groups. For the VPC that you created, note the ID of the default security group.
ibmcloud is security-groups{: pre} Example output with only the default security group of a randomly generated name,
preppy-swimmer-island-green-refreshment:ID Name Rules Network interfaces Created VPC Resource group 1a111a1a-a111-11a1-a111-111111111111 preppy-swimmer-island-green-refreshment 4 - 2019-08-12T13:24:45-04:00 <vpc_name>(bbbb222b-.) c3c33cccc33c333ccc3c33cc3c333cc3{: screen}
- Add a security group rule to allow inbound TCP traffic on ports 30000-32767.
ibmcloud is security-group-rule-add <security_group_ID> inbound tcp --port-min 30000 --port-max 32767{: pre}
- If you require VPC VPN access or classic infrastructure access into this cluster, add a security group rule to allow inbound UDP traffic on ports 30000-32767.
ibmcloud is security-group-rule-add <security_group_ID> inbound udp --port-min 30000 --port-max 32767{: pre}
-
Create a cluster in your VPC in the same zone as the subnet. By default, your cluster is created with a public and a private service endpoint. You can use the public service endpoint to access the Kubernetes master, such as to run
kubectlcommands, from your local machine. Your worker nodes can communicate with the master on the private service endpoint. For more information about the command options, see thecluster create vpc-gen2CLI reference docs.ibmcloud ks cluster create vpc-gen2 --name myvpc-cluster --zone us-south-1 --version 1.17 --flavor bx2.2x8 --workers 1 --vpc-id <vpc_ID> --subnet-id <vpc_subnet_ID>{: pre}
-
Check the state of your cluster. The cluster might take a few minutes to provision.
-
Verify that the cluster State is normal.
ibmcloud ks cluster ls --provider vpc-gen2{: pre}
-
Download the Kubernetes configuration files.
ibmcloud ks cluster config --cluster myvpc-cluster{: pre}
-
Verify that the
kubectlcommands run properly with your cluster by checking the Kubernetes CLI server version.kubectl version --short{: pre}
Example output:
Client Version: v1.17.3 Server Version: v1.17.3+IKS{: screen}
-
{: #vpc_ks_app} {: step}
Create a Kubernetes deployment to deploy a single app instance as a pod to your worker node in your VPC cluster. {: shortdesc}
The components that you deploy by completing this lesson are shown in the following diagram.
To deploy the app:
-
Clone the source code for the Hello world app{: external} to your user home directory. The repository contains different versions of a similar app in folders that each start with
Lab. Each version contains the following files:Dockerfile: The build definitions for the image.app.js: The Hello world app.package.json: Metadata about the app.
git clone https://github.com/IBM/container-service-getting-started-wt.git{: pre}
-
Navigate to the
Lab 1directory.cd 'container-service-getting-started-wt/Lab 1'{: pre}
-
Use an existing registry namespace or create one, such as
vpc-gen2.ibmcloud cr namespace-list{: pre}
ibmcloud cr namespace-add vpc-gen2{: pre}
-
Build a Docker image that includes the app files of the
Lab 1directory, and push the image to the {{site.data.keyword.registrylong_notm}} namespace that you created. If you need to change the app in the future, repeat these steps to create another version of the image. Note: Learn more about securing your personal information when you work with container images.Use lowercase alphanumeric characters or underscores (
_) only in the image name. Don't forget the period (.) at the end of the command. The period tells Docker to look inside the current directory for the Dockerfile and build artifacts to build the image.ibmcloud cr build -t us.icr.io/<namespace>/hello-world:1 .{: pre}
When the build is complete, verify that you see the following success message:
Successfully built <image_ID> Successfully tagged us.icr.io/<namespace>/hello-world:1 The push refers to a repository [us.icr.io/vpc-gen2/hello-world] 29042bc0b00c: Pushed f31d9ee9db57: Pushed 33c64488a635: Pushed 0804854a4553: Layer already exists 6bd4a62f5178: Layer already exists 9dfa40a0da3b: Layer already exists 1: digest: sha256:f824e99435a29e55c25eea2ffcbb84be4b01345e0a3efbd7d9f238880d63d4a5 size: 1576{: screen}
-
Create a deployment for your app. Deployments are used to manage pods, which include containerized instances of an app. The following command deploys the app in a single pod. For the purposes of this tutorial, the deployment is named hello-world-deployment, but you can give the deployment any name that you want.
kubectl create deployment hello-world-deployment --image=us.icr.io/vpc-gen2/hello-world:1{: pre}
Example output:
deployment.apps/hello-world-deployment created{: screen}
Learn more about securing your personal information when you work with Kubernetes resources.
-
Make the app accessible by exposing the deployment as a NodePort service. Because your VPC worker nodes are connected to a private subnet only, the NodePort is assigned only a private IP address and is not exposed on the public network. Other services that run on the private network can access your app by using the private IP address of the NodePort service.
kubectl expose deployment/hello-world-deployment --type=NodePort --name=hello-world-service --port=8080 --target-port=8080{: pre}
Example output:
service/hello-world-service exposed{: screen}
More about the expose parameters Parameter Description exposeExpose a Kubernetes resource, such as a deployment, as a Kubernetes service so that users can access the resource by using the IP address of the service. deployment/<hello-world-deployment>The resource type and the name of the resource to expose with this service. --name=<hello-world-service>The name of the service. --type=NodePortThe service type to create. In this lesson, you create a `NodePort` service. In the following lesson, you create a `LoadBalancer` service. --port=<8080>The port on which the service listens for external network traffic. --target-port=<8080>The port that your app listens on and to which the service directs incoming network traffic. In this example, the `target-port` is the same as the `port`, but other apps that you create might use a different port. -
Now that all the deployment work is done, you can test your app from within the cluster. Get the details to form the private IP address that you can use to access your app.
-
Get information about the service to see which NodePort was assigned. The NodePorts are randomly assigned when they are generated with the
exposecommand, but within 30000-32767. In this example, the NodePort is 30872.kubectl describe service hello-world-service{: pre}
Example output:
Name: hello-world-service Namespace: default Labels: run=hello-world-deployment Selector: run=hello-world-deployment Type: NodePort IP: 10.xxx.xx.xxx Port: <unset> 8080/TCP NodePort: <unset> 30872/TCP Endpoints: 172.30.xxx.xxx:8080 Session Affinity: None No events.{: screen}
-
List the pods that run your app, and note the pod name.
kubectl get pods{: pre}
Example output:
NAME READY STATUS RESTARTS AGE hello-world-deployment-d99cddb45-lmj2v 1/1 Running 0 2d{: screen}
-
Describe your pod to find out what worker node the pod is running on. In the example output, the worker node that the pod runs on is 10.xxx.xx.xxx.
kubectl describe pod hello-world-deployment-d99cddb45-lmj2v{: pre}
Example output:
Name: hello-world-deployment-d99cddb45-lmj2v Namespace: default Priority: 0 PriorityClassName: <none> Node: 10.xxx.xx.xxx/10.xxx.xx.xxx Start Time: Mon, 22 Apr 2019 12:40:48 -0400 Labels: pod-template-hash=d99cddb45 run=hello-world-deployment Annotations: kubernetes.io/psp=ibm-privileged-psp Status: Running IP: 172.30.xxx.xxx ...{: screen}
-
-
Log in to the pod so that you can make a request to your app from within the cluster.
kubectl exec -it hello-world-deployment-d99cddb45-lmj2v /bin/sh{: pre}
-
Make a request to the NodePort service by using the worker node private IP address and the node port that you previously retrieved.
wget -O - 10.xxx.xx.xxx:30872{: pre}
Example output:
Connecting to 10.xxx.xx.xxx:30872 (10.xxx.xx.xxx:30872) Hello world from hello-world-deployment-d99cddb45-lmj2v! Your app is up and running in a cluster! - 100% |*****************************************************************************************| 88 0:00:00 ETA{: screen}
To close your pod session, enter
exit.
{: #vpc_ks_vpc_lb} {: step}
Set up a VPC load balancer to expose your app on the public network. {: shortdesc}
When you create a Kubernetes LoadBalancer service in your cluster, a load balancer for VPC is automatically created in your VPC outside of your cluster. The load balancer is multizonal and routes requests for your app through the private NodePorts that are automatically opened on your worker nodes. The following diagram illustrates how a user accesses an app's service through the load balancer, even though your worker node is connected to only a private subnet.
-
Create a Kubernetes
LoadBalancerservice in your cluster to publicly expose the hello world app.kubectl expose deployment/hello-world-deployment --type=LoadBalancer --name=hw-lb-svc --port=8080 --target-port=8080{: pre}
Example output:
service "hw-lb-svc" exposed{: screen}
More about the expose parameters Component Description exposeExpose a Kubernetes resource, such as a deployment, as a Kubernetes service so that users can access the resource by using the VPC load balancer hostname. deployment/<hello-world-deployment>The resource type and the name of the resource to expose with this service. --name=<hello-world-service>The name of the service. --type=LoadBalancerThe Kubernetes service type to create. In this lesson, you create a `LoadBalancer` service. --port=<8080>The port on which the service listens for external network traffic. --target-port=<8080>The port that your app endpoint listens on and to which the service directs incoming network traffic. In this example, the `target-port` is the same as the `port`, but other apps that you create might use a different port. -
Verify that the Kubernetes
LoadBalancerservice is created successfully in your cluster. When you create the KubernetesLoadBalancerservice, a VPC load balancer is automatically created for you. The VPC load balancer assigns a hostname to your Kubernetes LoadBalancer service that you can see in the LoadBalancer Ingress field of your CLI output.The VPC load balancer takes a few minutes to provision in your VPC. Until the VPC load balancer is ready, you cannot access the Kubernetes
LoadBalancerservice through its hostname.kubectl describe service hw-lb-svc{: pre}
Example CLI output:
Name: hw-lb-svc Namespace: default Labels: app=hello-world-deployment Annotations: <none> Selector: app=hello-world-deployment Type: LoadBalancer IP: 172.21.xxx.xxx LoadBalancer Ingress: 1234abcd-us-south.lb.appdomain.cloud Port: <unset> 8080/TCP TargetPort: 8080/TCP NodePort: <unset> 32040/TCP Endpoints: Session Affinity: None External Traffic Policy: Cluster Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal EnsuringLoadBalancer 1m service-controller Ensuring load balancer Normal EnsuredLoadBalancer 1m service-controller Ensured load balancer{: screen}
-
Verify that the VPC load balancer is created successfully in your VPC. In the output, verify that the VPC load balancer has an Operating Status of
onlineand a Provision Status ofactive.The VPC load balancer is named in the format
kube-<cluster_ID>-<kubernetes_lb_service_UID>. To see your cluster ID, runibmcloud ks cluster get --cluster <cluster_name>. To see the KubernetesLoadBalancerservice UID, runkubectl get svc hw-lb-svc -o yamland look for the metadata.uid field in the output. {: tip}ibmcloud is load-balancers{: pre}
In the following example CLI output, the VPC load balancer that is named
kube-bh077ne10vqpekt0domg-046e0f754d624dca8b287a033d55f96eis created for thehw-lb-svcKubernetesLoadBalancerservice:ID Name Created Host Name Is Public Listeners Operating Status Pools Private IPs Provision Status Public IPs Subnets Resource Group 06496f64-a689-4693-ba23-320959b7b677 kube-bh077ne10vqpekt0domg-046e0f754d624dca8b287a033d55f96e 8 minutes ago 1234abcd-us-south.lb.appdomain.cloud yes 95482dcf-6b9b-4c6a-be54-04d3c46cf017 online 717f2122-5431-403c-b21d-630a12fc3a5a 10.1.1.1,10.1.1.2 active 169.1.1.1,169.1.1.2 c6540331-1c1c-40f4-9c35-aa42a98fe0d9 00809211b934565df546a95f86160f62{: screen}
-
Send a request to your app by curling the hostname and port of the Kubernetes
LoadBalancerservice that is assigned by the VPC load balancer. Example:curl 1234abcd-us-south.lb.appdomain.cloud:8080{: pre}
Example output:
Hello world from hello-world-deployment-5fd7787c79-sl9hn! Your app is up and running in a cluster!{: screen}
{: #vpc_ks_next}
Now that you have a VPC cluster, learn more about what you can do. {: shortdesc}
- Setting up block storage for your apps
- Overview of the differences between classic and VPC clusters
- VPC cluster limitations
- About the v2 API
- Comparison of Classic and VPC commands for the CLI
Need help, have questions, or want to give feedback on VPC clusters? Try posting in the Slack channel{: external}. {: tip}

