Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

1043 lines
31 KiB
Markdown
Raw Permalink Normal View History

2019-11-12 00:33:46 -08:00
---
2023-06-02 21:41:36 -07:00
title_tag: Deploy Kubernetes Apps | Crosswalk
meta_desc: This page gives you an overview on how to deploy Kubernetes applications to different cloud providers.
title: Apps
h1: Kubernetes Apps
2023-06-08 16:15:52 -07:00
meta_image: /images/docs/meta-images/docs-clouds-kubernetes-meta-image.png
menu:
clouds:
parent: kubernetes-guides
identifier: kubernetes-guides-apps
weight: 12
aliases:
- /docs/guides/crosswalk/kubernetes/apps/
---
2019-11-08 01:32:17 -08:00
The following are examples of how to create and use various types of Kubernetes
resources, and typical apps and workloads.
{{< chooser cloud "aws,azure,gcp" / >}}
2019-11-08 21:31:35 -08:00
{{% choosable cloud aws %}}
2019-11-08 21:31:35 -08:00
The full code for the AWS apps stack is on [GitHub][gh-repo-stack].
<!-- markdownlint-disable url -->
[gh-repo-stack]: https://github.com/pulumi/kubernetes-guides/tree/master/aws/06-apps
<!-- markdownlint-enable url -->
2019-11-08 21:31:35 -08:00
{{% /choosable %}}
2019-11-08 21:31:35 -08:00
{{% choosable cloud azure %}}
2019-11-08 21:31:35 -08:00
The full code for the Azure apps stack is on [GitHub][gh-repo-stack].
<!-- markdownlint-disable url -->
[gh-repo-stack]: https://github.com/pulumi/kubernetes-guides/tree/master/azure/06-apps
<!-- markdownlint-enable url -->
2019-11-08 21:31:35 -08:00
{{% /choosable %}}
2019-11-08 21:31:35 -08:00
{{% choosable cloud gcp %}}
2019-11-08 21:31:35 -08:00
The full code for the Google Cloud apps stack is on [GitHub][gh-repo-stack].
<!-- markdownlint-disable url -->
[gh-repo-stack]: https://github.com/pulumi/kubernetes-guides/tree/master/gcp/06-apps
<!-- markdownlint-enable url -->
2019-11-08 21:31:35 -08:00
{{% /choosable %}}
2019-11-08 21:31:35 -08:00
The full code for the apps is on [GitHub][gh-repo-stack].
<!-- markdownlint-disable url -->
[gh-repo-stack]: https://github.com/pulumi/kubernetes-guides/tree/master/apps
<!-- markdownlint-enable url -->
2019-11-10 15:19:47 -08:00
## Overview
Check out how to:
- [Overview](#overview)
- [Build and Deploy a Container](#build-and-deploy-a-container)
- [Deploy a Pod with a Sidecar](#deploy-a-pod-with-a-sidecar)
- [Deploy a Helm Chart](#deploy-a-helm-chart)
- [Deploy Wordpress](#deploy-wordpress)
- [Create a Deployment with a Secret](#create-a-deployment-with-a-secret)
- [Perform a ConfigMap Rollout on a Deployment](#perform-a-configmap-rollout-on-a-deployment)
- [Deploy a Job](#deploy-a-job)
- [Deploy a DaemonSet](#deploy-a-daemonset)
- [Deploy a CronJob](#deploy-a-cronjob)
- [Deploy a StatefulSet](#deploy-a-statefulset)
- [Learn More](#learn-more)
2019-11-10 15:19:47 -08:00
## Build and Deploy a Container
Build a Docker container image, push it to the registry, and deploy it to
Kubernetes.
{{% choosable cloud aws %}}
The full code for this app stack is on [GitHub][gh-aws-deploy-stack].
<!-- markdownlint-disable url -->
[gh-aws-deploy-stack]: https://github.com/pulumi/kubernetes-guides/tree/master/aws/06-apps/build-deploy-container
<!-- markdownlint-enable url -->
{{< chooser k8s-language "typescript,typescript-kx" >}}
2021-03-14 07:14:21 -07:00
{{< choosable k8s-language typescript >}}
```ts
import * as awsx from "@pulumi/awsx";
import * as k8s from "@pulumi/kubernetes";
// Create a repository.
const repo = new awsx.ecr.Repository("my-repo", {
forceDelete: true,
});
// Build a Docker image from a local Dockerfile context in the
// './node-app' directory, and push it to the registry.
const customImage = "node-app";
const appImage = new awsx.ecr.Image("image", {
repositoryUrl: repo.url,
path: `./${customImage}`,
});
// Create a k8s provider.
const provider = new k8s.Provider("provider", {
kubeconfig: config.kubeconfig,
namespace: config.appsNamespaceName,
});
// Create a Deployment of the built container.
const appLabels = { app: customImage };
const appDeployment = new k8s.apps.v1.Deployment("app", {
spec: {
selector: { matchLabels: appLabels },
replicas: 1,
template: {
metadata: { labels: appLabels },
spec: {
containers: [{
name: customImage,
image: appImage.imageUri,
ports: [{name: "http", containerPort: 80}],
}],
}
},
}
}, { provider: provider });
```
2021-03-14 07:14:21 -07:00
{{< /choosable >}}
2021-03-14 07:14:21 -07:00
{{< choosable k8s-language typescript-kx >}}
2019-11-12 00:24:03 -08:00
```ts
import * as awsx from "@pulumi/awsx";
import * as k8s from "@pulumi/kubernetes";
import * as kx from "@pulumi/kubernetesx";
// Create a repository.
const repo = new awsx.ecr.Repository("my-repo", {
forceDelete: true,
});
2019-11-12 00:24:03 -08:00
// Build a Docker image from a local Dockerfile context in the
// './node-app' directory, and push it to the registry.
const customImage = "node-app";
const appImage = repo.buildAndPushImage(`./${customImage}`);
// Create a k8s provider.
const provider = new k8s.Provider("provider", {
kubeconfig: config.kubeconfig,
namespace: config.appsNamespaceName,
});
// Define the Pod for the Deployment.
const pb = new kx.PodBuilder({
containers: [{
image: appImage.imageUri,
2019-11-12 00:24:03 -08:00
ports: { "http": 80 },
}],
});
// Create a Deployment of the Pod defined by the PodBuilder.
const appDeploymentKx = new kx.Deployment("app-kx", {
spec: pb.asDeploymentSpec(),
}, { provider: provider });
```
2021-03-14 07:14:21 -07:00
{{< /choosable >}}
{{< /chooser >}}
{{% /choosable %}}
{{% choosable cloud azure %}}
The full code for this app stack is on [GitHub][gh-azure-deploy-stack].
<!-- markdownlint-disable url -->
[gh-azure-deploy-stack]: https://github.com/pulumi/kubernetes-guides/tree/master/azure/06-apps/build-deploy-container
<!-- markdownlint-enable url -->
{{< chooser k8s-language "typescript,typescript-kx" >}}
2021-03-14 07:14:21 -07:00
{{< choosable k8s-language typescript >}}
```ts
import * as azure from "@pulumi/azure";
import * as docker from "@pulumi/docker";
import * as k8s from "@pulumi/kubernetes";
import * as pulumi from "@pulumi/pulumi";
// Create an Azure Resource Group
const resourceGroup = new azure.core.ResourceGroup("samples");
// Create a registry in ACR.
const registry = new azure.containerservice.Registry("myregistry", {
resourceGroupName: resourceGroup.name,
sku: "Basic",
adminEnabled: true,
});
// Build a Docker image from a local Dockerfile context in the
// './node-app' directory, and push it to the registry.
const customImage = "node-app";
const appImage = new docker.Image(customImage, {
imageName: pulumi.interpolate`${registry.loginServer}/${customImage}:v1.0.0`,
build: {
context: `./${customImage}`,
},
registry: {
server: registry.loginServer,
username: registry.adminUsername,
password: registry.adminPassword,
},
});
// Create a k8s provider.
const provider = new k8s.Provider("provider", {
kubeconfig: config.kubeconfig,
namespace: config.appsNamespaceName,
});
// Create a Deployment of the built container.
const appLabels = { app: customImage };
const appDeployment = new k8s.apps.v1.Deployment("app", {
spec: {
selector: { matchLabels: appLabels },
replicas: 1,
template: {
metadata: { labels: appLabels },
spec: {
containers: [{
name: customImage,
image: appImage.imageUri,
ports: [{name: "http", containerPort: 80}],
}],
}
},
}
}, { provider: provider });
```
2021-03-14 07:14:21 -07:00
{{< /choosable >}}
2021-03-14 07:14:21 -07:00
{{< choosable k8s-language typescript-kx >}}
2019-11-12 00:24:03 -08:00
```ts
import * as azure from "@pulumi/azure";
import * as k8s from "@pulumi/kubernetes";
import * as kx from "@pulumi/kubernetesx";
import * as docker from "@pulumi/docker";
import * as pulumi from "@pulumi/pulumi";
// Create an Azure Resource Group
const resourceGroup = new azure.core.ResourceGroup("samples");
// Create a registry in ACR.
const registry = new azure.containerservice.Registry("myregistry", {
resourceGroupName: resourceGroup.name,
sku: "Basic",
adminEnabled: true,
});
// Build a Docker image from a local Dockerfile context in the
// './node-app' directory, and push it to the registry.
const customImage = "node-app";
const appImage = new docker.Image(customImage, {
imageName: pulumi.interpolate`${registry.loginServer}/${customImage}:v1.0.0`,
build: {
context: `./${customImage}`,
},
registry: {
server: registry.loginServer,
username: registry.adminUsername,
password: registry.adminPassword,
},
});
// Create a k8s provider.
const provider = new k8s.Provider("provider", {
kubeconfig: config.kubeconfig,
namespace: config.appsNamespaceName,
});
// Define the Pod for the Deployment.
const pb = new kx.PodBuilder({
containers: [{
image: appImage.imageUri,
2019-11-12 00:24:03 -08:00
ports: { "http": 80 },
}],
});
// Create a Deployment of the Pod defined by the PodBuilder.
const appDeploymentKx = new kx.Deployment("app-kx", {
spec: pb.asDeploymentSpec(),
}, { provider: provider });
```
2021-03-14 07:14:21 -07:00
{{< /choosable >}}
{{< /chooser >}}
{{% /choosable %}}
{{% choosable cloud gcp %}}
The full code for this app stack is on [GitHub][gh-gcp-deploy-stack].
<!-- markdownlint-disable url -->
[gh-gcp-deploy-stack]: https://github.com/pulumi/kubernetes-guides/tree/master/gcp/06-apps/build-deploy-container
<!-- markdownlint-enable url -->
{{< chooser k8s-language "typescript,typescript-kx" >}}
2021-03-14 07:14:21 -07:00
{{< choosable k8s-language typescript >}}
```ts
import * as docker from "@pulumi/docker";
import * as gcp from "@pulumi/gcp";
import * as k8s from "@pulumi/kubernetes";
import * as pulumi from "@pulumi/pulumi";
// Get the Google Cloud project registry repository.
const registry = gcp.container.getRegistryRepositoryOutput();
// Get the repository URL
const repositoryUrl = registry.repositoryUrl;
// Build a Docker image from a local Dockerfile context in the
// './node-app' directory, and push it to the registry.
const customImage = "node-app";
const appImage = new docker.Image(customImage, {
imageName: pulumi.interpolate`${repositoryUrl}/${customImage}:v1.0.0`,
build: {
context: `./${customImage}`,
},
});
// Create a k8s provider.
const provider = new k8s.Provider("provider", {
kubeconfig: config.kubeconfig,
namespace: config.appsNamespaceName,
});
// Create a Deployment of the built container.
const appLabels = { app: customImage };
const appDeployment = new k8s.apps.v1.Deployment("app", {
spec: {
selector: { matchLabels: appLabels },
replicas: 1,
template: {
metadata: { labels: appLabels },
spec: {
containers: [{
name: customImage,
image: appImage.imageUri,
ports: [{name: "http", containerPort: 80}],
}],
}
},
}
}, { provider: provider });
```
2021-03-14 07:14:21 -07:00
{{< /choosable >}}
2019-11-12 00:24:03 -08:00
2021-03-14 07:14:21 -07:00
{{< choosable k8s-language typescript-kx >}}
2019-11-12 00:24:03 -08:00
```ts
import * as docker from "@pulumi/docker";
import * as gcp from "@pulumi/gcp";
import * as k8s from "@pulumi/kubernetes";
import * as kx from "@pulumi/kubernetesx";
import * as pulumi from "@pulumi/pulumi";
// Get the Google Cloud project registry repository.
const registry = gcp.container.getRegistryRepositoryOutput();
2019-11-12 00:24:03 -08:00
// Get the repository URL
const repositoryUrl = registry.repositoryUrl;
2019-11-12 00:24:03 -08:00
// Build a Docker image from a local Dockerfile context in the
// './node-app' directory, and push it to the registry.
const customImage = "node-app";
const appImage = new docker.Image(customImage, {
imageName: pulumi.interpolate`${repositoryUrl}/${customImage}:v1.0.0`,
2019-11-12 00:24:03 -08:00
build: {
context: `./${customImage}`,
},
});
// Create a k8s provider.
const provider = new k8s.Provider("provider", {
kubeconfig: config.kubeconfig,
namespace: config.appsNamespaceName,
});
// Define the Pod for the Deployment.
const pb = new kx.PodBuilder({
containers: [{
image: appImage.imageUri,
2019-11-12 00:24:03 -08:00
ports: { "http": 80 },
}],
});
// Create a Deployment of the Pod defined by the PodBuilder.
const appDeploymentKx = new kx.Deployment("app-kx", {
spec: pb.asDeploymentSpec(),
}, { provider: provider });
```
2021-03-14 07:14:21 -07:00
{{< /choosable >}}
{{< /chooser >}}
{{% /choosable %}}
2019-11-11 15:06:52 -08:00
## Deploy a Pod with a Sidecar
The full code for this app stack is on [GitHub][gh-wp-stack].
<!-- markdownlint-disable url -->
[gh-wp-stack]: https://github.com/pulumi/kubernetes-guides/tree/master/apps/pod-sidecar
<!-- markdownlint-enable url -->
2019-11-11 15:06:52 -08:00
Create a NGINX Pod with a Debian sidecar that prints to a file in a shared
volume of the Pod.
```ts
import * as k8s from "@pulumi/kubernetes";
2019-11-11 15:06:52 -08:00
// Create an example Pod with a Sidecar.
const pod = new k8s.core.v1.Pod("example", {
spec: {
2019-11-11 15:06:52 -08:00
restartPolicy: "Never",
volumes: [
{name: "shared-data", emptyDir: {}},
],
containers: [
{
2019-11-11 15:06:52 -08:00
name: "nginx",
image: "nginx",
resources: {requests: {cpu: "50m", memory: "50Mi"}},
volumeMounts: [
{ name: "shared-data", mountPath: "/usr/share/nginx/html"},
],
},
{
2019-11-11 15:06:52 -08:00
name: "debian-container",
image: "debian",
resources: {requests: {cpu: "50m", memory: "50Mi"}},
volumeMounts: [
{ name: "shared-data", mountPath: "/pod-data"},
],
command: [ "/bin/bash"],
args: ["-c", "echo Hello from the Debian container > /pod-data/index.html ; sleep infinity"],
}
],
}
}, { provider: provider });
2019-11-11 15:06:52 -08:00
```
2019-11-11 15:06:52 -08:00
Print out the contents of the shared file from the `nginx` container in the Pod.
```bash
$ kubectl exec -it example-<SUFFIX> -n `pulumi output stack appsNamespaceName` -c nginx -- cat /usr/share/nginx/html/index.html
```
2019-11-11 19:45:45 -08:00
## Deploy a Helm Chart
Deploy the [Helm chart][nginx-helm] into the `app-svcs` namespace created in [Configure
Cluster Defaults][crosswalk-k8s-defaults], and publicly expose it to the
Internet using a [load balanced Service][k8s-lb-svc].
> Note: NGINX requires a privileged PSP given its [use][nginx-priv-use] of `allowPrivilegeEscalation: true`.
```typescript
import * as k8s from "@pulumi/kubernetes";
// Deploy the NGINX ingress controller using the Helm chart.
const nginx = new k8s.helm.v3.Chart("nginx",
2019-11-11 19:45:45 -08:00
{
namespace: config.appSvcsNamespaceName,
chart: "nginx-ingress",
version: "1.24.4",
fetchOpts: {repo: "https://charts.helm.sh/stable/"},
2019-11-11 19:45:45 -08:00
values: {controller: {publishService: {enabled: true}}},
transformations: [
(obj: any) => {
// Do transformations on the YAML to set the namespace
if (obj.metadata) {
obj.metadata.namespace = config.appSvcsNamespaceName;
}
},
],
},
{providers: {kubernetes: provider}},
);
```
<!-- markdownlint-disable url -->
2019-11-11 19:45:45 -08:00
[nginx-priv-use]: https://github.com/helm/charts/blob/master/stable/nginx-ingress/values.yaml#L12
[k8s-lb-svc]: https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer
[nginx-helm]: https://github.com/helm/charts/tree/master/stable/nginx-ingress
[crosswalk-k8s-defaults]: /docs/clouds/kubernetes/guides/configure-defaults/#namespaces
<!-- markdownlint-enable url -->
2019-11-11 19:45:45 -08:00
## Deploy Wordpress
Create a Deployment of Wordpress.
The full code for this app stack is on [GitHub][gh-deploy-wp-stack].
<!-- markdownlint-disable url -->
[gh-deploy-wp-stack]: https://github.com/pulumi/kubernetes-guides/tree/master/apps/wordpress
<!-- markdownlint-enable url -->
2019-11-11 19:45:45 -08:00
```ts
import * as k8s from "@pulumi/kubernetes";
const wordpress = new k8s.apps.v1.Deployment("wordpress", {
spec: {
2019-11-12 00:24:03 -08:00
selector: { matchLabels: { app: "wordpress", release: "example" } },
strategy: { type: "RollingUpdate" },
2019-11-11 19:45:45 -08:00
replicas: 1,
template: {
metadata: { labels: { app: "wordpress", release: "example" } },
spec: {
2019-11-12 00:24:03 -08:00
hostAliases: [ { ip: "127.0.0.1", hostnames: [ "status.localhost"] } ],
2019-11-11 19:45:45 -08:00
containers: [
{
name: "wordpress",
image: "docker.io/bitnami/wordpress:5.2.4-debian-9-r0",
imagePullPolicy: "IfNotPresent",
env: [
{ name: "MARIADB_HOST", value: "mariadb" },
{ name: "WORDPRESS_DATABASE_NAME", value: "bitnami_wordpress" },
{ name: "WORDPRESS_DATABASE_USER", value: "bn_wordpress" },
{
name: "WORDPRESS_DATABASE_PASSWORD",
valueFrom: {
secretKeyRef: {
name: mariadbSecret.metadata.name,
key: "mariadb-password"
}
}
},
...
],
ports: [
{ name: "http", containerPort: 80 },
{ name: "https", containerPort: 443 }
],
volumeMounts: [
{
mountPath: "/bitnami/wordpress",
name: "wordpress-data",
subPath: "wordpress"
}
],
2019-11-12 00:24:03 -08:00
resources: { requests: { cpu: "300m", memory: "512Mi" } }
2019-11-11 19:45:45 -08:00
...
}
],
...
}
}
}
}, { provider: provider });
```
2019-11-10 15:19:47 -08:00
## Create a Deployment with a Secret
Create a [Deployment][k8s-deploy] NGINX that uses a [Secret][k8s-secret].
The full code for this app stack is on [GitHub][gh-deploy-secret-stack].
<!-- markdownlint-disable url -->
[gh-deploy-secret-stack]: https://github.com/pulumi/kubernetes-guides/tree/master/apps/deployment-secret
[k8s-deploy]: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
2019-11-12 00:24:03 -08:00
[k8s-secret]: https://kubernetes.io/docs/concepts/configuration/secret/
<!-- markdownlint-enable url -->
{{< chooser k8s-language "typescript,typescript-kx" >}}
{{% choosable k8s-language typescript %}}
```ts
import * as k8s from "@pulumi/kubernetes";
// Create a Secret with the database credentials.
const databaseSecret = new k8s.core.v1.Secret("db-secret", {
stringData: {
2019-11-11 13:22:22 -08:00
"database-username": config.databaseUsername,
"database-password": config.databasePassword,
}
}, { provider: provider });
// Create a Deployment that uses the database credentials as environment variables.
const appName = "nginx";
const appLabels = { app: appName };
const nginx = new k8s.apps.v1.Deployment(appName, {
metadata: { labels: appLabels },
spec: {
selector: {
matchLabels: appLabels,
},
replicas: 1,
template: {
metadata: { labels: appLabels },
spec: {
containers: [
{
image: "nginx",
name: "nginx",
env: [
{
name: "DATABASE_USERNAME",
valueFrom: {
secretKeyRef: {
name: databaseSecret.metadata.name,
key: "database-username"
}
}
},
{
name: "DATABASE_PASSWORD",
valueFrom: {
secretKeyRef: {
name: databaseSecret.metadata.name,
key: "database-password"
}
}
}
]
},
],
},
},
},
}, { provider: provider });
```
{{% /choosable %}}
{{% choosable k8s-language typescript-kx %}}
```ts
import * as kx from "@pulumi/kubernetesx";
// Create a KX Secret with the database credentials.
const databaseSecretKx = new kx.Secret("db-secret", {
stringData: {
2019-11-11 13:22:22 -08:00
"database-username": config.databaseUsername,
"database-password": config.databasePassword,
}
}, { provider: provider });
// Create a KX PodBuilder for the demo app.
2019-11-14 12:50:30 -07:00
const nginxPB = new kx.PodBuilder({
containers: [{
image: "nginx",
env: {
"DATABASE_USERNAME": databaseSecretKx.asEnvValue("database-username"),
"DATABASE_PASSWORD": databaseSecretKx.asEnvValue("database-password"),
}
}]
});
// Create a KX Deployment from the KX PodBuilder by transforming it into a DeploymentSpec.
// The deployment use database credentials as environment variables.
const nginxDeployment = new kx.Deployment(appName, {
spec: nginxPB.asDeploymentSpec({replicas: 1})
}, { provider: provider });
```
{{% /choosable %}}
{{< /chooser >}}
2019-11-10 15:19:47 -08:00
## Perform a ConfigMap Rollout on a Deployment
For a complete example, check out our Kubernetes [Graceful App Rollout][tutorial-app-rollout]
2019-11-12 00:24:03 -08:00
tutorial for more details on how to update a Deployment automatically
when it's ConfigMap changes.
[tutorial-app-rollout]: /registry/packages/kubernetes/how-to-guides/configmap-rollout/
2019-11-12 00:24:03 -08:00
## Deploy a Job
Deploy a [Job][k8s-job] of a Perl program.
The full code for this app stack is on [GitHub][gh-job-stack].
<!-- markdownlint-disable url -->
[gh-job-stack]: https://github.com/pulumi/kubernetes-guides/tree/master/apps/job
2019-11-12 00:24:03 -08:00
[k8s-job]: https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion
<!-- markdownlint-enable url -->
2019-11-12 00:24:03 -08:00
{{< chooser k8s-language "typescript,typescript-kx" >}}
{{% choosable k8s-language typescript %}}
2019-11-12 00:24:03 -08:00
```ts
import * as k8s from "@pulumi/kubernetes";
// Create an example Job.
const exampleJob = new k8s.batch.v1.Job("example-job", {
spec: {
template: {
spec: {
containers: [
{
name: "pi",
image: "perl",
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"],
}
],
restartPolicy: "Never"
}
},
}
}, { provider: provider });
```
{{% /choosable %}}
{{% choosable k8s-language typescript-kx %}}
2019-11-12 00:24:03 -08:00
```ts
import * as kx from "@pulumi/kubernetesx";
// Create the PodBuilder for the Job.
const pb = new kx.PodBuilder({
containers: [{
name: "pi",
image: "perl",
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"],
}],
restartPolicy: "Never",
});
// Create a Job using the Pod defined by the PodBuilder.
const exampleJobKx = new kx.Job("example-job-kx", {
spec: pb.asJobSpec(),
}, { provider: provider });
```
{{% /choosable %}}
{{< /chooser >}}
2019-11-12 00:24:03 -08:00
2019-11-10 15:19:47 -08:00
## Deploy a DaemonSet
2019-11-11 19:45:45 -08:00
Deploy a [DaemonSet][k8s-ds] of NGINX across all nodes in the cluster.
The full code for this app stack is on [GitHub][gh-ds-stack].
<!-- markdownlint-disable url -->
[gh-ds-stack]: https://github.com/pulumi/kubernetes-guides/tree/master/apps/daemonset
[k8s-ds]: https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/
<!-- markdownlint-enable url -->
{{< chooser k8s-language "typescript,typescript-kx" >}}
{{% choosable k8s-language typescript %}}
```ts
import * as k8s from "@pulumi/kubernetes";
// Create a DaemonSet that deploys nginx to each worker node.
const appName = "nginx";
const appLabels = { app: appName };
const nginx = new k8s.apps.v1.DaemonSet(appName, {
metadata: { labels: appLabels },
spec: {
selector: {
matchLabels: appLabels,
},
template: {
metadata: { labels: appLabels },
spec: {
containers: [
{
image: "nginx",
name: "nginx",
},
],
},
},
},
}, { provider: provider });
```
{{% /choosable %}}
{{% choosable k8s-language typescript-kx %}}
2019-11-12 00:24:03 -08:00
Coming Soon.
{{% /choosable %}}
{{< /chooser >}}
2019-11-10 15:19:47 -08:00
## Deploy a CronJob
Deploy a [CronJob][k8s-cj] of a command that runs every minute.
The full code for this app stack is on [GitHub][gh-cronjob-stack].
<!-- markdownlint-disable url -->
[gh-cronjob-stack]: https://github.com/pulumi/kubernetes-guides/tree/master/apps/cronjob
[k8s-cj]: https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/
<!-- markdownlint-enable url -->
{{< chooser k8s-language "typescript,typescript-kx" >}}
{{% choosable k8s-language typescript %}}
```ts
import * as k8s from "@pulumi/kubernetes";
// Create an example CronJob.
const exampleCronJob = new k8s.batch.v1beta1.CronJob("example-cronjob", {
spec: {
schedule: "*/1 * * * *",
jobTemplate: {
spec: {
template: {
spec: {
containers: [
{
name: "hello",
image: "busybox",
args: ["/bin/sh", "-c", "date; echo Hello from the Kubernetes cluster"],
}
],
restartPolicy: "OnFailure"
}
}
}
},
}
}, { provider: provider });
```
{{% /choosable %}}
{{% choosable k8s-language typescript-kx %}}
Coming soon.
{{% /choosable %}}
{{< /chooser >}}
2019-11-10 15:19:47 -08:00
## Deploy a StatefulSet
Deploy a [StatefulSet][k8s-ss] of [MariaDB][mariadb].
The full code for this app stack is on [GitHub][gh-ss-stack].
<!-- markdownlint-disable url -->
[gh-ss-stack]: https://github.com/pulumi/kubernetes-guides/tree/master/apps/statefulset
[k8s-ss]: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/
[mariadb]: https://mariadb.org/
<!-- markdownlint-enable url -->
{{< chooser k8s-language "typescript,typescript-kx" >}}
{{% choosable k8s-language typescript %}}
```ts
import * as k8s from "@pulumi/kubernetes";
// Deploy MariaDB as a StatefulSet.
const mariadb = new k8s.apps.v1.StatefulSet("mariadb", {
spec: {
selector: {
matchLabels: {
app: "mariadb",
release: "example",
component: "master"
}
},
serviceName: "mariadb",
replicas: 1,
updateStrategy: {
type: "RollingUpdate"
},
template: {
metadata: {
labels: {
app: "mariadb",
release: "example",
component: "master"
}
},
spec: {
serviceAccountName: "default",
securityContext: {
fsGroup: 1001,
runAsUser: 1001
},
affinity: {
podAntiAffinity: {
preferredDuringSchedulingIgnoredDuringExecution: [
{
weight: 1,
podAffinityTerm: {
topologyKey: "kubernetes.io/hostname",
labelSelector: {
matchLabels: {
app: "mariadb",
release: "example"
}
}
}
}
]
}
},
containers: [
{
name: "mariadb",
image: "docker.io/bitnami/mariadb:10.3.18-debian-9-r36",
imagePullPolicy: "IfNotPresent",
env: [
{
name: "MARIADB_ROOT_PASSWORD",
valueFrom: {
secretKeyRef: {
name: mariadbSecret.metadata.name,
key: "mariadb-root-password"
}
}
},
{ name: "MARIADB_USER", value: "bn_wordpress" },
{
name: "MARIADB_PASSWORD",
valueFrom: {
secretKeyRef: {
name: mariadbSecret.metadata.name,
key: "mariadb-password"
}
}
},
{ name: "MARIADB_DATABASE", value: "bitnami_wordpress" }
],
ports: [
{ name: "mysql", containerPort: 3306 }
],
livenessProbe: {
exec: {
command: ["sh", "-c", "exec mysqladmin status -uroot -p$MARIADB_ROOT_PASSWORD"],
},
initialDelaySeconds: 120,
periodSeconds: 10,
timeoutSeconds: 1,
successThreshold: 1,
failureThreshold: 3
},
readinessProbe: {
exec: {
command: ["sh", "-c", "exec mysqladmin status -uroot -p$MARIADB_ROOT_PASSWORD"]
},
initialDelaySeconds: 30,
periodSeconds: 10,
timeoutSeconds: 1,
successThreshold: 1,
failureThreshold: 3
},
volumeMounts: [
{
name: "data",
mountPath: "/bitnami/mariadb"
},
{
name: "config",
mountPath: "/opt/bitnami/mariadb/conf/my.cnf",
subPath: "my.cnf"
}
]
}
],
volumes: [
{
name: "config",
configMap: {
name: mariadbCM.metadata.name
}
}
]
},
},
volumeClaimTemplates: [
{
metadata: {
name: "data",
labels: {
app: "mariadb",
component: "master",
release: "example",
}
},
spec: {
accessModes: [
"ReadWriteOnce"
],
resources: {
requests: {
storage: "8Gi"
}
}
}
}
]
}
}, { provider: provider });
```
{{% /choosable %}}
{{% choosable k8s-language typescript-kx %}}
Coming soon.
{{% /choosable %}}
{{< /chooser >}}
2019-11-11 13:22:22 -08:00
## Learn More
To learn more about how to work with Kubernetes and Pulumi, check out the
[Kubernetes Tutorials][k8s-tutorials] for details.
[k8s-tutorials]: /registry/packages/kubernetes/how-to-guides/